鼠標在圖片上畫矩形(ROI)區域並保存ROI區域

#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圖像
Mat run_roi;  //實時ROI
Mat img5;
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);
		    copyMakeBorder(roi,img5, 50, 50, 50, 50, BORDER_REFLECT101);
			imwrite("..\\Template.jpg",img5);
			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);
			rectangle(img, rect, Scalar(0, 0, 255), 2);
			//namedWindow("SignROI");
			imshow("SrcImage", img);
		}
		break;
	}
}

int main()
{
	src = imread("C:\\Users\\xx\\Desktop\\Lena.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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章