http://blog.csdn.net/sac761/article/details/51926853
opencv 截取轮廓中的图像——实现PS中利用蒙版抠图的功能(Using Opencv extract area circled by contour)
顺手秀了一把英语~~
我时常感慨,要是PhotoShop要是开源的多好啊,这得造福多少从事计算机视觉的码农们啊~ 既然不开源,那就自己摸索吧,我希望从这篇博文开始我能一步步把PS中的功能给分解出来,欢迎指正交流
我们很容易用 findContours() 函数将图像中的轮廓提取出来,但是并没有将轮廓所包围的图像输出的函数,以下是几个有类似功能的函数:
cvimageroi(): 得到包围 ROI (感兴趣区域)的矩形区域,可以直接把轮廓点集作为参数给进去然后返回包围这个轮廓的最佳矩形点集,然后再用 Mat的成员函数Mat(Rec)把这个区域提取出来。遗憾的是这样只能提取矩形区域,无法提取不规则区域。
boundingRect() :这个同上一个是一样的功能,也是得到矩形区域。
进入正题
首先将原图像灰度化,二值化,然后提取轮廓,进行排除、去噪处理之后用drawContours()函数把轮廓填充为白色。具体做法是:
Mat hole(res.size(), CV_8U, Scalar(0)); //新建一个黑色的遮罩图层
cv::drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); //在遮罩图层上,将轮廓里面的空间用白色像素填充
之后将原图用copyTo()函数叠加到遮罩图层上,就大功告成了。
#include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include <iostream> using namespace cv; using namespace std; void main() { Mat original = imread("D:\\res.png" ); namedWindow("My original" ); imshow("My original" , original); Mat gray = original; cv::cvtColor(gray, gray, CV_RGB2GRAY); int thresh_size = (100 / 4) * 2 + 1; adaptiveThreshold(gray, gray, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, thresh_size, thresh_size / 3); morphologyEx(gray, gray, MORPH_OPEN, Mat()); vector<vector<Point> > contours; cv::findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); vector<vector<Point>> contours1; for ( int i = 0; i < contours.size(); ++i) { if (contours[i].size() > 200) { contours1.push_back(contours[i]); } } Mat hole(gray.size(), CV_8U, Scalar(0)); cv::drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); namedWindow("My hole" ); imshow("My hole" , hole); Mat crop(original.rows, original.cols, CV_8UC3); original.copyTo(crop, hole); namedWindow("My warpPerspective" ); imshow("My warpPerspective" , crop); waitKey(0); }