在優化工程代碼效率。從一系列輪廓合集中減去其中的一個輪廓分量,之前都是通過二值圖像相減的方式,即把總輪廓繪製在一副圖像上Img_1,再把要減去的分量繪製在另一幅圖像Img_2上,然後通過圖像相減得到差值圖像Img_3,再從Img3中找出相減後的結果。今天突然靈機一動,發現這麼減來減去簡直太浪費資源了,明明一副圖像就能搞定呀!只要在一副圖像上繪製總輪廓,然後用背景像素繪製要減去的輪廓不就OK了?傻呵呵~自我鄙視一下。
雖然很簡單,還是看一下兩種實現方式的實現效果吧。
第一種實現方式,兩圖做減法:
void contours_subtraction_1(Mat Img, vector<vector<Point> > contours1, vector<vector<Point> > contours2)
{
Mat Img_1(Img.size(), CV_8UC1, Scalar(0));
Mat Img_2(Img.size(), CV_8UC1, Scalar(0));
//分別在兩個新創建的圖像上繪製兩個輸入的輪廓
drawContours(Img_1, contours1, -1, Scalar(255), -1);
drawContours(Img_2, contours2, -1, Scalar(255), -1);
Mat diffImg;
absdiff(Img_1, Img_2, diffImg);
imshow("subtract_result_1", diffImg);
waitKey(0);
//從差值圖像diffImg中提取出輪廓,即爲差值輪廓
}
第二種實現方式,直接用背景像素繪製要減去的輪廓:
void contours_subtraction_2(Mat Img, vector<vector<Point> > contours1, vector<vector<Point> > contours2)
{
Mat Img_1(Img.size(), CV_8UC1, Scalar(0));
//在新創建的圖像上繪製總輪廓
drawContours(Img_1, contours1, -1, Scalar(255), -1);
//在同一副圖像上繪製要減去的輪廓,但用背景像素值繪製
drawContours(Img_1, contours2, -1, Scalar(0), -1);
imshow("subtract_result_2", Img_1);
waitKey(0);
}
測試一下:
#include <iostream>
#include <vector>
#include <math.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
int main()
{
//首先,建立兩個輪廓,爲了簡單起見,分別用一個圓形和一個矩形創建兩個輪廓
//創建一個單通道背景圖
Mat img(Size(300,300), CV_8UC1, Scalar(0));
//創建一個圓形輪廓
circle(img, Point(100,100), 50, Scalar(255), -1);
vector<vector<Point> > circle_contours;
findContours(img, circle_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//再創建一個矩形輪廓
Rect rect(100,100,100,100);
rectangle(img, rect, Scalar(255), -1);
vector<vector<Point> > circle_rect_contours;
findContours(img, circle_rect_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//繪製出總輪廓
Mat blkImg(img.size(), CV_8UC1, Scalar(0));
drawContours(blkImg, circle_rect_contours, -1, Scalar(255), -1);
imshow("circle+rectangle", blkImg);
waitKey(0);
//調用方法1實現輪廓相減
contours_subtraction_1(img, circle_rect_contours, circle_contours);
//調用方法2實現輪廓相減
contours_subtraction_2(img, circle_rect_contours, circle_contours);
return 0;
}
結果:
一樣一樣的。