Grabcut原理見:https://blog.csdn.net/zouxy09/article/details/8534954
grabCut() 函數
cv::grabCut(image, //輸入圖像
result, //分段結果
rectangle, // 包含前景的矩形
bgModel,fgModel, // 前景、背景
1, // 疊代次數
cv::GC_INIT_WITH_RECT); // 用矩形
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
const char* winTitle = "input image";
Rect rect;
Mat src, image, mask, bgMode, fgMode;
int numRun = 0;
bool init = false;
void runGrabcut()
{
if (rect.width < 2 || rect.height < 2)
return;
if (init)
grabCut(src, mask, rect, bgMode, fgMode, 1); // 完成第一次的初始化之後,就不需要用矩形了,直接用model了。
else
{
grabCut(src, mask, rect, bgMode, fgMode, 1, GC_INIT_WITH_RECT);
init = true;
}
}
void setROIMask()
{
mask.setTo(Scalar(GC_BGD));
rect.x = max(0, rect.x);
rect.y = max(0, rect.y);
rect.width = min(rect.width, src.cols - rect.x);
rect.height = min(rect.height, src.rows - rect.y);
mask(rect).setTo(Scalar(GC_PR_FGD));
}
void showImage()
{
Mat result, binMask;
binMask.create(mask.size(), CV_8UC1);
binMask = mask & 1;
if (init)
src.copyTo(result, binMask);
else
src.copyTo(result);
rectangle(result, rect, Scalar(0, 0, 255), 2, 8);
imshow(winTitle, result);
}
void onMouse(int event, int x, int y, int flags, void* param)
{
switch (event)
{
case EVENT_LBUTTONDOWN:
rect.x = x;
rect.y = y;
rect.width = 1;
rect.height = 1;
init = false;
numRun = 0;
break;
case EVENT_MOUSEMOVE:
if (flags * EVENT_FLAG_LBUTTON)// 左鍵按住
{
rect = Rect(Point(rect.x, rect.y), Point(x, y));
showImage();
}
break;
case EVENT_LBUTTONUP:
if (rect.width > 1 && rect.height > 1)
{
setROIMask();
showImage();
}
break;
default:
break;
}
}
int main()
{
src = imread("D:/source/images/flower3.png");
if (src.empty())
{
puts("read image empty");
system("pause");
return -1;
}
mask.create(src.size(), CV_8UC1);
mask.setTo(Scalar::all(GC_BGD));
namedWindow(winTitle, CV_WINDOW_AUTOSIZE);
setMouseCallback(winTitle, onMouse);
imshow(winTitle, src);
while (true)
{
char c = (char)waitKey(0);
if (c == 27) break;
if (c == 'n')
{
numRun++;
runGrabcut();
showImage();
printf("numRun = %d\n", numRun);
}
}
return 0;
}
将花扣出來後的效果: