天天看点

OpenCV图像处理使用笔记(一)——使用鼠标选取任何形状的ROI

前言

1.在图像处理中,会用鼠标选择一个感兴趣的区域进行相关的操作,我这里演示如何用鼠标选择任何形状的ROI,就你Ps的抠图一样,使用鼠标左键选择一个任何形状的区域,生成新的图像。

2.我演示的代码环境是,IDE是VS2015,使用的是OpenCV3.30这个版本。

选择任何形状的ROI

#include <iostream>    
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>     

using namespace cv;

//定义全局坐标系
Point prev_pt = Point(-1, -1);
Mat src, background_img, foreground_img;

void on_mouse(int event, int x, int y, int flags, void*)

{
	//松开鼠标左键或不是按住左键拖拽的动作时,把坐标还原 
	if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))      
	{
		prev_pt = Point(-1, -1);
	}
	//按下左键
	else if (event == CV_EVENT_LBUTTONDOWN)                                    
	{
		prev_pt = Point(x, y);
	}
	//移动鼠标并按住左键拖拽
	else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_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 == CV_EVENT_RBUTTONUP)                          
	{
		Mat dst;
		//画线闭合区域被白色填充显示在原始图像上
		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("4.jpg");
	//初始化前景和背景模板      
	foreground_img = Mat(image.size(), CV_8UC1, Scalar(0));													
	
	image.copyTo(src);
	//显示原图
	namedWindow("原图", 0);
	imshow("原图", src);    
	cvSetMouseCallback("原图", on_mouse, 0);

	waitKey(0);
	return 0;
}

           

结果

1.运行之后,按下鼠标左键,对着要选择的区域拖动鼠标描边,闭合之后松开左键,点击右键,得到ROI区域。

OpenCV图像处理使用笔记(一)——使用鼠标选取任何形状的ROI

2.如果不闭合,按漫水填充的算法,会得到整张图像。

OpenCV图像处理使用笔记(一)——使用鼠标选取任何形状的ROI