opencv学习笔记五十八:grabCut抠图

基本步骤:

  • 基于交互式界面由用户选择前景区域;
  • 定义一个单通道的输出掩码,0为背景,1为前景,2为可能的背景,3为可能的前景;
  • grabCut抠图;将输出结果与可能的前景作比较得到可能的前景;
  • 定义三通道的结果图像;
  • 从原图中拷贝可能的前景到结果图像;
grabCut( InputArray img, InputOutputArray mask, Rect rect,
                           InputOutputArray bgdModel, InputOutputArray fgdModel,
                           int iterCount, int mode = GC_EVAL );

 img:输入原图像;

mask:输出掩码;

rect:用户选择的前景矩形区域;

bgModel:输出背景图像;

fgModel:输出前景图像;

iterCount:迭代次数;

#include<opencv2\opencv.hpp>
using namespace cv;
void onMouse(int event, int x, int y, int flags, void* userdata);
Rect rect;
Mat src,roiImg, result;
void showImg();
int main(int arc, char** argv) { 
	src = imread("3.jpg");
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src); 
	setMouseCallback("input", onMouse);
	//定义输出结果,结果为:GC_BGD =0(背景),GC_FGD =1(前景),GC_PR_BGD = 2(可能的背景), GC_PR_FGD = 3(可能的前景)		
	Mat result = Mat::zeros(src.size(), CV_8UC1);
	// GrabCut 抠图
	//两个临时矩阵变量,作为算法的中间变量使用
	Mat bgModel, fgModel;
	char c = waitKey(0);
	if (c == 'g') {
		grabCut(src, result, rect, bgModel, fgModel, 1, GC_INIT_WITH_RECT);
		//比较result的值为可能的前景像素才输出到result中
		compare(result, GC_PR_FGD, result, CMP_EQ);
		// 产生输出图像
		Mat foreground(src.size(), CV_8UC3, Scalar(255, 255, 255));
		//将原图像src中的result区域拷贝到foreground中
		src.copyTo(foreground, result);
		imshow("output", foreground);
	}
	waitKey(0); 
	return 0;
}


void showImg() {
	src.copyTo(roiImg);
	rectangle(roiImg, rect, Scalar(0, 0, 255), 2);
	imshow("input", roiImg);
}
//鼠标选择矩形框
void onMouse(int event, int x, int y, int flags, void* userdata){
	switch (event)
	{
	case CV_EVENT_LBUTTONDOWN://鼠标左键按下事件
		rect.x = x;
		rect.y = y;
		rect.width = 1;
		rect.height = 1;
		break;
	case CV_EVENT_MOUSEMOVE://鼠标移动事件
		if (flags && CV_EVENT_FLAG_LBUTTON) {
			rect = Rect(Point(rect.x, rect.y), Point(x, y));
			showImg();
		}
		break;
	case EVENT_LBUTTONUP://鼠标弹起事件
		if (rect.width > 1 && rect.height > 1) {
			showImg();
		}
		break;
	default:
		break;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_24946843/article/details/82827168