opencv-图像抠图

首先将原图像灰度化,二值化,然后提取轮廓,进行排除、去噪处理之后用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]);
		}
	}
	/*可以加入以下功能*/
	//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);
}


  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值