本文是《OpenCV實戰從入門到精通》系列之第7篇
【OpenCV】OpenCV實戰從入門到精通之一 -- OpenCV宏的講解
【OpenCV】OpenCV實戰從入門到精通之二 -- OpenCV如何進行圖像腐蝕操作
【OpenCV】OpenCV實戰從入門到精通之三 -- canny邊緣檢測
【OpenCV】OpenCV實戰從入門到精通之四 -- 常用的函數講解(mat、imread、imshow、imwrite、nameWindow)
【OpenCV】OpenCV實戰從入門到精通之五 -- 教你使用Rect()函數
【OpenCV】OpenCV實戰從入門到精通之六 -- 教你如何使用滑動條-createTrackbar()函數
目錄
第二個參數可能不很理解,其實第二個參數最關鍵:它是我們對鼠標操作的反應,當鼠標有哪些操作,我們可以出現不同的響應。 如果我們沒有設定這些操作,那麼就不會有反應
函數原型
void setMouseCallback(conststring& winname, MouseCallback onMouse,void* userdata=0)
第一個參數:窗口名
第二個參數:被調用的函數指針。
函數原型:void Foo(int event,int x,int y,int flags, void *param)
第三個參數:用戶 定義的傳遞到回調函數的參數,默認0
第二個參數可能不很理解,其實第二個參數最關鍵:它是我們對鼠標操作的反應,當鼠標有哪些操作,我們可以出現不同的響應。 如果我們沒有設定這些操作,那麼就不會有反應
舉例:設定了單擊左鍵就跳出窗口,設定單擊右鍵無任何操作。那麼程序就會根據你的指令進行選擇。
//----------------【】-----------------------
//
//-------------------------------------------
//----------------【頭文件、命名空間包含範圍】-----------------------
// 包含的命名空間和頭文件
//---------------------------------------------------------------
#include<opencv2\opencv.hpp>
using namespace cv;
#define WINDOW_NAME "【程序窗口】" //爲窗口標題定義宏
//----------------【全局函數聲明】-----------------------
// 提示幫助ShowHlepText
//-------------------------------------------
void on_MouseHandle(int event, int x, int y ,int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);
void ShowHlepText();
//----------------【全局變量聲明的部分】-----------------------
//
//-------------------------------------------
Rect g_rectangle;//長方形
bool g_bDrawingBox = false;//是否進行繪製
RNG g_rng(12345);
//----------------【main()函數】-----------------------
//
//-------------------------------------------
int main()
{
//【1】準備參數
g_rectangle = Rect(-1,-1,0,0);
Mat srcImage(600, 800, CV_8UC3), tempImage;//生成一個600x800的窗口
srcImage.copyTo(tempImage);
g_rectangle = Rect(-1, -1, 0, 0);
srcImage = Scalar::all(0);
//【2】設置鼠標回調函數
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);//爲指定窗口設定回調函數,也就是自己設定判斷鼠標操作
//【3】程序的主循環,當繪製標識符爲真,進行繪製
while (1)
{
srcImage.copyTo(tempImage); //複製到臨時變量
if (g_bDrawingBox) //標識符爲真,就繪製
DrawRectangle(tempImage, g_rectangle);
imshow(WINDOW_NAME, tempImage);
if (waitKey(10) == 27) break; //按下Esc鍵,程序退出
}
return 0;
}
//----------------【on_MouseHandle()函數】-----------------------
// 記錄鼠標的信息,比如鼠標移動、左鍵按鍵
//-------------------------------------------
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_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
//左鍵按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//記錄起始點
}
break;
//左鍵擡起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;
//對寬、高小於0如何處理
if (g_rectangle.width < 0)
{
g_rectangle.x + g_rectangle.width;
g_rectangle.width *= -1;
}
if (g_rectangle.height < 0)
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
//調用函數繪製
DrawRectangle(image, g_rectangle);
}
break;
}
}
//----------------【DrawRectangle()函數】-----------------------
//
//-------------------------------------------
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//隨機顏色,(左上角+右下角頂點)
}
結果