在优化工程代码效率。从一系列轮廓合集中减去其中的一个轮廓分量,之前都是通过二值图像相减的方式,即把总轮廓绘制在一副图像上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;
}
结果:
一样一样的。