opencv 截取轮廓中的图像——实现PS中的抠图功能 Opencv extract area circled by contour

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()函数叠加到遮罩图层上,就大功告成了。

  1. #include "opencv2/imgproc.hpp"  
  2. #include "opencv2/highgui.hpp"  
  3. #include <iostream>  
  4. using namespace cv;  
  5. using namespace std;  
  6. void main() {  
  7.     Mat original = imread("D:\\res.png");  
  8.     namedWindow("My original");  
  9.     imshow("My original", original);  
  10.     Mat gray = original;  
  11.     cv::cvtColor(gray, gray, CV_RGB2GRAY);//灰度化  
  12.   
  13.     int thresh_size = (100 / 4) * 2 + 1; //自适应二值化阈值  
  14.     adaptiveThreshold(gray, gray, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, thresh_size, thresh_size / 3);  
  15.     morphologyEx(gray, gray, MORPH_OPEN, Mat());//形态学开运算去噪点  
  16.   
  17.     vector<vector<Point> > contours;  
  18.     cv::findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找轮廓  
  19.     vector<vector<Point>> contours1;  
  20.     for (int i = 0; i < contours.size(); ++i)  
  21.     {  
  22.         if (contours[i].size() > 200)//将比较小的轮廓剔除掉  
  23.         {  
  24.             contours1.push_back(contours[i]);  
  25.         }  
  26.     }  
  27.     /*可以加入以下功能*/  
  28.     //vector<vector<Point>> contours2;  
  29.     //vector<Point> approx_poly;//存放顶点  
  30.     //for (int i = 0; i < contours1.size(); ++i)  
  31.     //{  
  32.         //double eps = contours1[i].size()*0.08;//精度  
  33.         //approxPolyDP(contours1[i], approx_poly, eps, true);//用另一条顶点较少的曲线来逼近一条曲线或者一个多边形  
  34.         //if ((approx_poly.size() != 4) || (!isContourConvex(approx_poly)))//提取只有4个顶点的轮廓和凸多边形  
  35.         //{  
  36.         //  continue;  
  37.         //}  
  38.         //else {  
  39.     //contours2.push_back(contours1[i]);  
  40.         //}  
  41.     //}  
  42.     Mat hole(gray.size(), CV_8U, Scalar(0)); //遮罩图层  
  43.     cv::drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); //在遮罩图层上,用白色像素填充轮廓  
  44.         namedWindow("My hole");  
  45.         imshow("My hole", hole);  
  46.     Mat crop(original.rows, original.cols, CV_8UC3);  
  47.     original.copyTo(crop, hole);//将原图像拷贝进遮罩图层  
  48.     namedWindow("My warpPerspective");  
  49.     imshow("My warpPerspective", crop);  
  50.     waitKey(0);  
  51. }  
#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]);
		}
	}
	/*可以加入以下功能*/
	//vector<vector<Point>> contours2;
	//vector<Point> approx_poly;//存放顶点
	//for (int i = 0; i < contours1.size(); ++i)
	//{
		//double eps = contours1[i].size()*0.08;//精度
		//approxPolyDP(contours1[i], approx_poly, eps, true);//用另一条顶点较少的曲线来逼近一条曲线或者一个多边形
		//if ((approx_poly.size() != 4) || (!isContourConvex(approx_poly)))//提取只有4个顶点的轮廓和凸多边形
		//{
		//	continue;
		//}
		//else {
	//contours2.push_back(contours1[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);
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于OpenCV的C++代码实现图像轮廓匹配轮廓筛选: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 读取模板图像和目标图像 Mat templateImg = imread("template.jpg", IMREAD_GRAYSCALE); Mat targetImg = imread("target.jpg", IMREAD_GRAYSCALE); // 定义轮廓存储变量 vector<vector<Point>> templateContours, targetContours; vector<Vec4i> templateHierarchy, targetHierarchy; // 寻找模板图像和目标图像轮廓 findContours(templateImg, templateContours, templateHierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); findContours(targetImg, targetContours, targetHierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 定义轮廓筛选阈值 double minArea = 100; double maxArea = 1000; // 对模板图像轮廓进行筛选 vector<vector<Point>> filteredTemplateContours; for (int i = 0; i < templateContours.size(); i++) { double area = contourArea(templateContours[i]); if (area > minArea && area < maxArea) { filteredTemplateContours.push_back(templateContours[i]); } } // 对目标图像轮廓进行筛选 vector<vector<Point>> filteredTargetContours; for (int i = 0; i < targetContours.size(); i++) { double area = contourArea(targetContours[i]); if (area > minArea && area < maxArea) { filteredTargetContours.push_back(targetContours[i]); } } // 显示筛选后的模板图像和目标图像轮廓 Mat templateContoursImg = Mat::zeros(templateImg.size(), CV_8UC3); drawContours(templateContoursImg, filteredTemplateContours, -1, Scalar(0, 255, 0), 2); imshow("Filtered Template Contours", templateContoursImg); Mat targetContoursImg = Mat::zeros(targetImg.size(), CV_8UC3); drawContours(targetContoursImg, filteredTargetContours, -1, Scalar(0, 255, 0), 2); imshow("Filtered Target Contours", targetContoursImg); waitKey(0); return 0; } ``` 注:以上代码的`template.jpg`和`target.jpg`分别为模板图像和目标图像,可以根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值