opencv鼠标操作:选择提取任意区域

opencv鼠标操作:选择提取任意区域


主要思路:


  1.  通过鼠标事件,选择封闭的图形;
  2. 对封闭图形做为掩膜,对原图抠图。


用到的函数:


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

 

猜你喜欢

转载自blog.csdn.net/youngybird/article/details/70792940
今日推荐