企業(yè)信用網(wǎng)查詢網(wǎng)站優(yōu)化推廣培訓(xùn)
文章目錄
- opencv鼠標事件函數(shù)setMouseCallback()詳解
- 1、鼠標事件函數(shù):
- (1)鼠標事件函數(shù)原型:setMouseCallback(),此函數(shù)會在調(diào)用之后不斷查詢回調(diào)函數(shù)onMouse(),直到窗口銷毀
- (2)回調(diào)函數(shù)onMouse(),可隨意命名,但是要與 setMouseCallback()函數(shù)里的回調(diào)函數(shù)名稱一致
- 2、代碼示例:
- (1)main.cpp
- (2)頭文件demo.h
- (3)demo.cpp
- (4)效果演示
opencv鼠標事件函數(shù)setMouseCallback()詳解
1、鼠標事件函數(shù):
(1)鼠標事件函數(shù)原型:setMouseCallback(),此函數(shù)會在調(diào)用之后不斷查詢回調(diào)函數(shù)onMouse(),直到窗口銷毀
void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0
)參數(shù)解釋:winname:窗口名稱;onMouse:回調(diào)函數(shù);userdata:傳遞給回調(diào)函數(shù)用戶自定義的外部數(shù)據(jù),userdata是一個 void 類型的指針;
(2)回調(diào)函數(shù)onMouse(),可隨意命名,但是要與 setMouseCallback()函數(shù)里的回調(diào)函數(shù)名稱一致
void onMouse(int event, int x, int y, int flags, void *userdata
) 參數(shù)解釋:
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 //中鍵雙擊
);
x和y:鼠標指針在圖像坐標系的坐標;
flags:鼠標事件標志的常量;
userdata:回調(diào)函數(shù)接收,用戶自定義的外部數(shù)據(jù),userdata是一個 void 類型的指針;
2、代碼示例:
利用鼠標事件函數(shù),提取ROI區(qū)域:
(1)main.cpp
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>using namespace cv;
using namespace std;int main() {//讀取圖像,BGR存儲在Mat矩陣里Mat src = cv::imread("C:\\cpp\\image\\suzy4.jpg");if (src.empty()) {printf("could not load image..../n");return -1;}Demo demo;demo.mouseEvent(src);waitKey();destroyAllWindows();return 0;
}
(2)頭文件demo.h
#include <opencv2/opencv.hpp>using namespace cv;class Demo
{
public:void mouseEvent(Mat &image);
private:};
(3)demo.cpp
#include <Demo.h>using namespace std;Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
static void onMouse(int event, int x, int y, int flags, void *userdata) {/*** 對指針userdata,進行轉(zhuǎn)換和解引用的操作,將userdata指向的Mat對象,賦值給名為image的變量,以便后續(xù)對圖像數(shù)據(jù)的處理:* userdata是一個void類型的指針,需要轉(zhuǎn)換為Mat類型的指針,然后用*運算符解引用,得到Mat對象,再賦值給名為image的變量,這樣就可以對image進行操作了;*/Mat image = *((Mat*)userdata);if (event == EVENT_LBUTTONDOWN) {// 起點坐標sp.x = x;sp.y = y;std::cout << "start point:" << sp << std::endl;}else if (event == EVENT_LBUTTONUP) {ep.x = x;ep.y = y;// 結(jié)束點坐標int dx = ep.x - sp.x;int dy = ep.y - sp.y;if (dx > 0 && dy > 0) {Rect box(sp.x, sp.y, dx, dy);temp.copyTo(image);imshow("ROI區(qū)域", image(box));rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);imshow("鼠標繪制", image);// ready for next drawingsp.x = -1;sp.y = -1;}}else if (event == EVENT_MOUSEMOVE) {if (sp.x > 0 && sp.y > 0) {ep.x = x;ep.y = y;int dx = ep.x - sp.x;int dy = ep.y - sp.y;if (dx > 0 && dy > 0) {Rect box(sp.x, sp.y, dx, dy);temp.copyTo(image);rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);imshow("鼠標繪制", image);}}}
}void Demo::mouseEvent(Mat &image) {namedWindow("鼠標事件", WINDOW_AUTOSIZE);/*** 由于回調(diào)函數(shù)需要傳入的是一個void類型指針,我們先取image的地址,再將&image強制轉(zhuǎn)換為void類型指針,具體操作如下:* &image:獲取變量image的內(nèi)存地址,即Mat對象的指針;* (void*):是一個強制類型轉(zhuǎn)換,將image的地址轉(zhuǎn)換為void類型指針,這樣就可以將參數(shù)傳遞給回調(diào)函數(shù)了;*/setMouseCallback("鼠標繪制", onMouse, (void*)(&image));imshow("鼠標繪制", image);temp = image.clone();
}