Open CV 學習筆記:滑鼠操作(回撥函式)
阿新 • • 發佈:2019-02-17
一、指定滑鼠訊息回撥函式 SetMouseCallback
opencv中的滑鼠響應的函式是setMouseCallback()。
c++: void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
- winname:視窗的名字
- onMouse:滑鼠響應函式,回撥函式。指定窗口裡每次滑鼠時間發生的時候,被呼叫的函式指標。 這個函式的原型應該為void on_Mouse(int event, int x, int y, int flags, void* param);
- userdate:傳給回撥函式的引數
- event是 CV_EVENT_*變數之一
- EVENT_MOUSEMOVE 滑動
- EVENT_LBUTTONDOWN 左擊
- EVENT_RBUTTONDOWN 右擊
- EVENT_MBUTTONDOWN 中鍵點選
- EVENT_LBUTTONUP 左鍵放開
- EVENT_RBUTTONUP 右鍵放開
- EVENT_MBUTTONUP 中鍵放開
- EVENT_LBUTTONDBLCLK 左鍵雙擊
- EVENT_RBUTTONDBLCLK 右鍵雙擊
- EVENT_MBUTTONDBLCLK 中鍵雙擊
- x和y是滑鼠指標在影象座標系的座標(不是視窗座標系)
- flags是CV_EVENT_FLAG的組合,flag的狀態有:
- EVENT_FLAG_LBUTTON 左鍵拖拽
- EVENT_FLAG_RBUTTON 右鍵拖拽
- EVENT_FLAG_MBUTTON 中鍵拖拽
- EVENT_FLAG_CTRLKEY 按住Ctrl不放
- EVENT_FLAG_SHIFTKEY 按住Shift不放
- EVENT_FLAG_ALTKEY 按住Alt不放
- param是使用者定義的傳遞到setMouseCallback函式呼叫的引數。
示例:利用滑鼠繪製矩形
#include <opencv2/opencv.hpp> #include <vector> #include <stdio.h> #define WINDOW_NAME "chengxuchuangkou" using namespace cv; void on_MouseHandle(int event,int x,int y,int flags,void* param); void DrawRectangle(cv::Mat& img,cv::Rect box); Rect g_rectangele; bool g_bDrawingBox = false; RNG g_rng(12345); int main(int argc,char** argv){//畫矩形視窗 g_rectangele = Rect(-1,-1,0,0); Mat srcImage(600,800,CV_8UC3),tempImage; srcImage.copyTo(tempImage); srcImage = cv::Scalar::all(0); namedWindow(WINDOW_NAME); setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage); while(1){ //imshow("temp",srcImage); srcImage.copyTo(tempImage); if(g_bDrawingBox) DrawRectangle(tempImage,g_rectangele); imshow(WINDOW_NAME,tempImage); if(waitKey(10) == 27) break; } return 0; } void on_MouseHandle(int event,int x,int y,int flags,void* param){//回撥函式 Mat& image = *(cv::Mat*) param; switch(event){//相應不同的滑鼠事件 case EVENT_MOUSEMOVE:{ if(g_bDrawingBox){ g_rectangele.width = x - g_rectangele.x; g_rectangele.height = y - g_rectangele.y; } } break; case EVENT_LBUTTONDOWN:{ g_bDrawingBox = true; g_rectangele = Rect(x,y,0,0); } break; case EVENT_LBUTTONUP:{ g_bDrawingBox = false; if(g_rectangele.width < 0){ g_rectangele.x += g_rectangele.width; g_rectangele.width *= -1; } if(g_rectangele.height < 0){ g_rectangele.y += g_rectangele.height; g_rectangele.height *= -1; } DrawRectangle(image,g_rectangele); } break; } } void DrawRectangle(cv::Mat& img,cv::Rect box){//繪製矩形 printf("%d %d\n",box.width,box.height); rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255))); }
二、建立滑動條createTrackbar()函式
opencv中的滑動條建立函式是createTrackbar()。
- C++:int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)
-
Parameters: - trackbarname – Name of the created trackbar.在標籤中顯示的文字(提示滑動條的用途)
- winname – Name of the window that will be used as a parent of the created trackbar.建立的滑動條要放置窗體的名字
- value – Optional pointer to an integer variable whose value reflects the position of the slider. Upon creation, the slider position is defined by this variable.滑動條的初始位置
- count – Maximal position of the slider. The minimal position is always 0.滑動條的最大位置
- onChange – Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void*); ,
where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only value is
updated.
- 每當滑動條的值改變, 就會呼叫 on_trackbar 回撥函式
- userdata – User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.
The function createTrackbar creates a trackbar (a slider or range control) with the specified name and range, assigns a variable valueto be a position syncronized with the trackbar and specifies the callback function onChange to be called on the trackbar position change. The created trackbar is displayed in the specified window winname.
示例:影象對比度和亮度的調節
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int g_nBrightValue;
int g_nContrastValue;
Mat g_srcImage,g_dstImage;
static void On_BrightAndContrast(int,void *){
for(int i = 0;i < g_dstImage.rows;i++){
for(int j = 0;j < g_dstImage.cols;j++){
for(int k = 0;k < 3;k++){
g_dstImage.at<Vec3b>(i,j)[k] = static_cast<uchar>(g_srcImage.at<Vec3b>(i,j)[k]*(g_nContrastValue*0.01)+g_nBrightValue);
}
}
}
imshow("原始視窗",g_srcImage);
imshow("效果視窗",g_dstImage);
}
int main(){
g_srcImage = imread("img.jpg");
if(!g_srcImage.data){
cout<<"input error!"<<endl;
return 0;
}
g_dstImage = Mat::zeros(g_srcImage.size(),g_srcImage.type());
g_nBrightValue = 70;
g_nContrastValue = 70;
namedWindow("效果視窗",1);
createTrackbar("Brightness","效果視窗",&g_nBrightValue,200,On_BrightAndContrast);
createTrackbar("Contrast","效果視窗",&g_nContrastValue,300,On_BrightAndContrast);
On_BrightAndContrast(g_nBrightValue,0);
On_BrightAndContrast(g_nContrastValue,0);
while(waitKey(0) == 'q') {}
return 0;
}