opencv鼠标操作:选择提取任意区域
主要思路:
- 通过鼠标事件,选择封闭的图形;
- 对封闭图形做为掩膜,对原图抠图。
用到的函数:
setMouseCallback()函数
了解了鼠标回调函数的调用机制后再来看一下创建回调函数的函数setMouseCallback();
原型:
void setMouseCallback(const string& winname, //图像视窗名称 MouseCallback onMouse, //鼠标响应函数,监视到鼠标操作后调用并处理相应动作 void* userdata = 0 //鼠标响应处理函数的ID,识别号 );
OnMouseAction()响应函数
鼠标事件回调函数onMouse按照固定格式创建响应函数:
void OnMouseAction(int event,int x,int y,int flags,void *ustc)
event事件代表了鼠标的各种操作,详细看一下各个event事件:
Event: #define CV_EVENT_MOUSEMOVE 0 //滑动 #define CV_EVENT_LBUTTONDOWN 1 //左键点击 #define CV_EVENT_RBUTTONDOWN 2 //右键点击 #define CV_EVENT_MBUTTONDOWN 3 //中键点击 #define CV_EVENT_LBUTTONUP 4 //左键放开 #define CV_EVENT_RBUTTONUP 5 //右键放开 #define CV_EVENT_MBUTTONUP 6 //中键放开 #define CV_EVENT_LBUTTONDBLCLK 7 //左键双击 #define CV_EVENT_RBUTTONDBLCLK 8 //右键双击 #define CV_EVENT_MBUTTONDBLCLK 9 //中键双击
int x,int y,代表鼠标位于窗口的(x,y)坐标位置,即Point(x,y);
int flags,代表鼠标的拖拽事件,以及键盘鼠标联合事件;
函数指针 void *ustc标识了所响应的事件函数,相当于自定义了一个OnMouseAction()函数的ID。
一.鼠标选择封闭图形:
void on_mouse(int event, int x, int y, int flags, void* yybird ) { if (!img.data) { printf("image is empty!\n"); return; } if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))/*初始化坐标*/ Point pt = Point(x, y); //上一个坐标点 pre_point = Point(-1, -1); else if(event == CV_EVENT_LBUTTONDOWN ) pre_point = Point(x, y); /*画出封闭图形*/ else if(event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON)) { if (pre_point.x < 0) { pre_point = pt; }//处理第一次 line(img,pre_point,pt,Scalar(0,0,255),1,8,0); line(inpaint_mask,pre_point,pt,Scalar(255,255,255),1,8,0); //坐标点传递 pre_point = pt; imshow("image", img); } }
/*
* 文件名称: image_ANYROI
* 作 者: youngybird
* 完成日期: 2017 年 4 月 26 日
* 版 本 号:opencv2.4.9 + vs2015
* 对任务及求解方法的描述部分:
* 使用语言:C/C++
*/
int main(int argc, char** argv) { img0 = imread("narotu.png",1); img = img0.clone();
//掩膜设为全黑,到时候封闭边界为255,方便检测 inpaint_mask = img0.clone(); inpaint_mask = Scalar::all(0); namedWindow("image", 1); imshow("image", img); cvSetMouseCallback("image", on_mouse, 0); waitKey(0); return 0; }
二.通过掩膜抠图(右击操作)
if (event==CV_EVENT_RBUTTONUP)//右击选择框图 { //涂色 floodFill(inpaint_mask, Point(x, y), Scalar(255, 255, 255)); //制作掩膜 Mat inpaint_mask_gray=inpaint_mask.clone(); cvtColor(inpaint_mask, inpaint_mask_gray, COLOR_BGR2GRAY); threshold(inpaint_mask_gray,inpaint_mask_gray,254,255,THRESH_BINARY); imshow("选取的区域", inpaint_mask_gray); //扣出选择的图像 img0.copyTo(inpaint_mask, inpaint_mask_gray); imshow("show", inpaint_mask); }
效果图:
原图:
选择封闭图形:
最后抠出来的图:
注明:
函数解释,参考: -牧野-
设计思路参考:zang141588761