1. 程式人生 > >OpenCV入門:ROI感興趣區域(滑鼠事件選定區域)

OpenCV入門:ROI感興趣區域(滑鼠事件選定區域)

OpenCV入門:ROI感興趣區域(滑鼠事件選定區域)

部落格 http://blog.csdn.net/qq_23968185/article/details/51335291

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

using namespace std;
using namespace cv;

bool draw;
Mat src;//原始影象  
Mat roi;//ROI影象
Point cursor;//初始座標   
Rect rect;//標記ROI的矩形框

/*
	void onMouse(int event, int x, int y, int flags, void *param);
	第一個引數,滑鼠操作時間的整數代號,在opencv中,event滑鼠事件總共有10中,從0-9依次代表如下:

	EVENT_MOUSEMOVE      =0,    //滑動
	EVENT_LBUTTONDOWN    =1,    //左鍵點選
	EVENT_RBUTTONDOWN    =2,    //右鍵點選
	EVENT_MBUTTONDOWN    =3,    //中間點選
	EVENT_LBUTTONUP      =4,    //左鍵釋放
	EVENT_RBUTTONUP      =5,    //右鍵釋放
	EVENT_MBUTTONUP      =6,    //中間釋放
	EVENT_LBUTTONDBLCLK  =7,    //左鍵雙擊
	EVENT_RBUTTONDBLCLK  =8,    //右鍵雙擊
	EVENT_MBUTTONDBLCLK  =9     //中間釋放

	第二個引數,代表滑鼠位於視窗的(x,y)座標位置,視窗左上角預設為原點,向右為x軸,向下為y軸;
	第三個引數,代表滑鼠的拖拽事件,以及鍵盤滑鼠聯合事件,總共有32種事件,這裡不再贅述。
	第四個引數,函式引數的編號。
*/
void onMouse(int event, int x, int y, int flags, void *param)
{
	Mat img = src.clone();
	switch (event)
	{
		//按下滑鼠左鍵
	case CV_EVENT_LBUTTONDOWN:
		//點選滑鼠影象時,清除之前ROI影象的顯示視窗  
		cvDestroyWindow("ROI");
		//存放起始座標  
		cursor = Point(x, y);
		//初始化起始矩形框  
		rect = Rect(x, y, 0, 0);
		draw = true;
		break;

		//鬆開滑鼠左鍵      
	case CV_EVENT_LBUTTONUP:
		if (rect.height > 0 && rect.width > 0)
		{
			//將img中的矩形區域複製給roi,並顯示在SignROI視窗 
			roi = img(Rect(rect.x, rect.y, rect.width, rect.height));
			rectangle(img, rect, Scalar(0, 0, 255), 2);
			namedWindow("SignROI");
			imshow("SignROI", img);

			//將畫過矩形框的影象用原影象還原  
			src.copyTo(img);
			imshow("SrcImage", img);

			//顯示ROI影象
			namedWindow("ROI");
			imshow("ROI", roi);
			waitKey(0);
		}
		draw = false;
		break;

		//移動游標
	case CV_EVENT_MOUSEMOVE:
		if (draw)
		{
			//用MIN得到左上點作為矩形框的起始座標,如果不加這個,畫矩形時只能向一個方向進行  
			rect.x = MIN(x, cursor.x);
			rect.y = MIN(y, cursor.y);
			rect.width = abs(cursor.x - x);
			rect.height = abs(cursor.y - y);
			//防止矩形區域超出影象的範圍  
			rect &= Rect(0, 0, src.cols, src.rows);
		}
		break;
	}
}

int main()
{
	src = imread("C:\\Users\\Phajaan\\Desktop\\bylw\\opencv\\男槍.jpg");
	if (src.data == 0)
	{
		cout << "圖片不存在" << endl;
		return -1;
	}
	namedWindow("SrcImage");
	imshow("SrcImage", src);
	/*
		void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0 );
		Parameters:
		第一個引數,windows視窗名稱,對名為winname的視窗進行滑鼠監控;
		第二個引數,滑鼠響應處理函式,監聽滑鼠的點選,移動,鬆開,判斷滑鼠的操作型別,並進行響應的函式處理;
		第三個引數,滑鼠響應處理函式的ID,與滑鼠相應處理函式相匹配就行,暫時只用到預設為0的情況。
	*/
	setMouseCallback("SrcImage", onMouse, NULL);
	waitKey();
	return 0;
}

效果圖: