1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4
5 using namespace cv;
6 using namespace std;
7
8 int numRun = 0;
9 Rect rect;
10 bool init = false;
11 Mat src, image;
12 Mat mask, bgModel, fgModel;//mask,背景,前景
13 const char* winTitle = "input image";
14
15 void onMouse(int event, int x, int y, int flags, void* param);
16 void setROIMask();
17 void showImage();
18 void runGrabCut();
19 int main(int argc, char** argv) {
20 src = imread("tx.png", 1);
21 if (src.empty()) {
22 printf("could not load image...\n");
23 return -1;
24 }
25 mask.create(src.size(), CV_8UC1);
26 mask.setTo(Scalar::all(GC_BGD));
27
28 namedWindow(winTitle, CV_WINDOW_AUTOSIZE);//
29 setMouseCallback(winTitle, onMouse, 0);//设置鼠标反馈事件
30 imshow(winTitle, src);
31
32 while (true) {
33 char c = (char)waitKey(0);
34 if (c == 'n') {
35 runGrabCut();//运行GrabCut算法
36 numRun++;
37 showImage();
38 printf("current iteative times : %d\n", numRun);//当前迭代次数
39 }
40 if ((int)c == 27) {
41 break;
42 }
43 }
44
45 waitKey(0);
46 return 0;
47 }
48
49 void showImage() {
50 Mat result, binMask;
51 binMask.create(mask.size(), CV_8UC1);
52 binMask = mask & 1;
53 if (init) {
54 src.copyTo(result, binMask);
55 } else {
56 src.copyTo(result);//将src图像拷贝到result中
57 }
58 imwrite("tx2.png",result);
59 rectangle(result, rect, Scalar(0, 0, 255), 2, 8);//在result上绘制红色矩形框rect
60 imshow(winTitle, result);
61 }
62
63 void setROIMask() {
64 // GC_FGD = 1
65 // GC_BGD =0;
66 // GC_PR_FGD = 3
67 // GC_PR_BGD = 2
68 mask.setTo(GC_BGD);
69 rect.x = max(0, rect.x);
70 rect.y = max(0, rect.y);
71 rect.width = min(rect.width, src.cols - rect.x);
72 rect.height = min(rect.height, src.rows - rect.y);
73 mask(rect).setTo(Scalar(GC_PR_FGD));
74 }
75
76 //鼠标事件函数
77 void onMouse(int event, int x, int y, int flags, void* param) {
78 switch (event)
79 {
80 case EVENT_LBUTTONDOWN://鼠标左键按下
81 rect.x = x;//矩形左上角x,y坐标
82 rect.y = y;
83 rect.width = 1;//矩形线条宽度、高度
84 rect.height = 1;
85 init = false;
86 numRun = 0;
87 break;
88 case EVENT_MOUSEMOVE://鼠标移动
89 if (flags & EVENT_FLAG_LBUTTON) {
90 rect = Rect(Point(rect.x, rect.y), Point(x, y));
91 showImage();//显示带矩形框的图像
92 }
93 break;
94 case EVENT_LBUTTONUP://鼠标左键松开
95 if (rect.width > 1 && rect.height > 1) {
96 setROIMask();
97 showImage();
98 }
99 break;
100 default:
101 break;
102 }
103 }
104
105 //运行GrabCut函数
106 void runGrabCut() {
107 if (rect.width < 2 || rect.height < 2) {
108 return;
109 }
110
111 if (init) {
112 grabCut(src, mask, rect, bgModel, fgModel, 1);
113 } {
114 grabCut(src, mask, rect, bgModel, fgModel, 1, GC_INIT_WITH_RECT);
115 init = true;
116 }
117 }