用图像分割之最大连通域算法得到最大轮廓矩形框,再使用grabcut分割:
#include<cmath>
using namespace cv;
using namespace std;
int main()
{
Mat srcImage = imread( "test_image.png" ,0);
if( !srcImage.data )
{
cout << "读取失败" << endl;
return 0;
}
namedWindow( "原始图", CV_WINDOW_NORMAL );
imshow( "原始图" , srcImage );
Mat dstImage;
// threshold只针对二值化图像
threshold( srcImage , dstImage ,228.0 , 255.0 ,CV_THRESH_BINARY|CV_THRESH_OTSU );
namedWindow( "dstImage", CV_WINDOW_NORMAL );
imshow( "dstImage" , dstImage );
//threshold(srcImage, srcImage,27, 255, CV_THRESH_BINARY);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours( dstImage , contours , hierarchy , CV_RETR_CCOMP , CV_CHAIN_APPROX_SIMPLE );
vector<Point> maxcontours ; //最大轮廓
double maxArea = 0;
// vector<vector<Point>>::const_iterator itContours = contours.begin();
for( size_t i = 0; i < contours.size();i++ )
{
double area = contourArea( contours[i] );
if( area > maxArea )
{
maxArea = area;
maxcontours = contours[i];
}
}
Rect maxRect = boundingRect( maxcontours ); //查找矩形框
Mat result1 , result2;
dstImage.copyTo( result1 );
dstImage.copyTo( result2 );
for( size_t i = 0; i < contours.size(); i++ )
{
Rect r = boundingRect( contours[i] );
rectangle( result1 , r , Scalar( 255 ) );
}
namedWindow( "all regions", CV_WINDOW_NORMAL );
imshow( "all regions" , result1 );
waitKey(100);
rectangle( result2 , maxRect , Scalar(255 ) );
namedWindow( "largest regions", CV_WINDOW_NORMAL );
imshow( "largest regions" , result2 );
waitKey(100);
Mat srcMarks,temp,img0;
temp = imread("test_image.png");
//namedWindow("原图",CV_WINDOW_NORMAL);
// imshow("原图", temp);
//resize(temp,img,Size(temp.cols/2,temp.rows/2),0,0,INTER_LINEAR);
// namedWindow("resize",CV_WINDOW_NORMAL);
// imshow("resize", img);
img0 = temp.clone();
int cols=temp.cols, rows=temp.rows;
temp.copyTo(srcMarks);
cv::rectangle(srcMarks, maxRect, cv::Scalar(255, 0, 0),1,1,0);
Mat result; // 4种可能结果
Mat bgModel, fgModel; // 背景/前景
grabCut(srcMarks, result, maxRect, bgModel, fgModel, 5, GC_INIT_WITH_RECT);
compare(result,GC_PR_FGD,result,CMP_EQ);//得到前景mask
Mat foreground(temp.size(),CV_8UC3,Scalar::all(255));
img0.copyTo(foreground,result);
namedWindow("grabcut",CV_WINDOW_NORMAL);
imshow("grabcut",foreground);
waitKey();
}