程序还不完善:
但是有点bug,在首次单击鼠标画线时会闪出一条从(0,0)到鼠标位置的线段。
#include <iostream>
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
//定义全局
Point prev_pt = Point(-1, -1);
Mat src, background_img, foreground_img;
//按住左键拖拽选取点并连线,右键一松开就形成 ROI
void on_mouse(int event, int x, int y, int flags, void *) { 形参x,y是鼠标点击的位置
//松开鼠标左键或不是按住左键拖拽的动作时,把坐标还原
if(event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON)) {
prev_pt = Point(-1, -1);
}
//按下左键
else if(event == EVENT_LBUTTONDOWN) {
prev_pt = Point(x, y);
}
//移动鼠标并按住左键拖拽
else if(event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) {
Point pt = Point(x, y);
//前景模板上划线
line(foreground_img, prev_pt, pt, Scalar(255), 2, 8, 0);
//原图上划线 Scalar::all(255)意思就是BGR通道像素值全为255
line(src, prev_pt, pt, Scalar::all(255), 2, 8, 0);
//起点等于终点,说明曲线要比
prev_pt = pt;
imshow("原图", src);
}
//点击右键,截取所选区域
if(event == EVENT_RBUTTONUP) {
Mat dst, multi;
//画线闭合区域被白色填充显示在原始图像上
floodFill(foreground_img, Point(x, y), Scalar(255));
// img中被FG_mask掩盖后的图像附到FG中显示
src.copyTo(dst, foreground_img);
namedWindow("ROI", 0);
imshow("ROI", dst);
}
}
int main() {
Mat image = imread("../data/lena-gray.jpg");
//初始化前景和背景模板
foreground_img = Mat(image.size(), CV_8UC1, Scalar(0));
image.copyTo(src);
imshow("原图", src);
//调用出错
setMouseCallback("原图", on_mouse, 0);
waitKey(0);
return 0;
}
第一步:在原图上左键拖拽画出闭合轮廓,接着,在原图上右键单击
第二步(有误):最后在原图上右键双击
1)在所选区域外的右键单击,就这样了
2)在所选区域内右键单击,就这样了
理论上应该是这样的: