Grabcut自动分割算法(前景物体检测)

算法的原理参见papaer:“GrabCut” — Interactive Foreground Extraction using Iterated Graph Cuts


grabcut函数原理

      即选定一个四边形框,把框中的图像作为grabcut的一个输入参数,表示该框中的像素可能属于前景,但框外的部分一定属于背景

在opencv 中grabcut 原函数的定义:


//! segments the image using GrabCut algorithm

CV_EXPORTS_W void grabCut

InputArray img, 

InputOutputArray mask,

 Rect rect,(包含前景的矩形)
InputOutputArray bgdModel, (前景)

InputOutputArray fgdModel,(背景)
int iterCount, (迭代次数)

int mode = GC_EVAL );


rectangle原函数:

CV_EXPORTS void rectangle

(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness=1,

int lineType=8, int shift=0);


本例程对整幅图像进行物体检测,即用grabcut检测前景物体。

程序运行的速度与iteration(即迭代的次数)有关。iteration越大,运行时间越长。

#include 
#include 
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include
using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
	//计算时间
	clock_t start, end;
	start = clock();

	
	Mat image = imread("1.jpg");
	Mat result; // 分割结果 (4种可能取值)
	Mat bgModel, fgModel; // 模型(内部使用)
	
	// 设定矩形,该矩形的长宽分别-1
	Rect rectangle(1, 1, image.cols - 1, image.rows - 1);
	grabCut(image, result, rectangle, bgModel, fgModel, 1, cv::GC_INIT_WITH_RECT);
	
	// 得到可能为前景的像素
	compare(result, cv::GC_PR_FGD, result, cv::CMP_EQ);
	// 生成输出图像
	Mat foreground(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
	image.copyTo(foreground, result); // 不复制背景数据

	// 包含矩形的原始图像
	cv::rectangle(image, rectangle, cv::Scalar(0, 0, 0), 1);


	cv::namedWindow("Orginal Image");
	cv::imshow("Orginal Image", image);

	// 输出前景图像结果
	cv::namedWindow("Foreground Of Segmented Image");
	cv::imshow("Foreground Of Segmented Image", foreground);

	end = clock();
	cout << "Run time: " << (double)(end - start) / CLOCKS_PER_SEC << "S" << endl;

	cvWaitKey(0); //等待退出

	//cvReleaseImage(&image);

	return 0;
}


效果如图:



原图像

Grabcut自动分割算法(前景物体检测)_第1张图片

运行之后的结果(白色部分为背景)

Grabcut自动分割算法(前景物体检测)_第2张图片

你可能感兴趣的:(图像处理)