基礎學習筆記之opencv(5):實現鼠標選定矩形框


  opencv編寫程序中,用鼠標選定矩形框經常用到。編程時看似很簡單的邏輯思路,如果對opencv中的Rect不是很了解的話,那實現的效果就不是特別理想,比如說雖然我們習慣性用鼠標從左上到右下選擇,但是偶爾也會從左下到右上選擇等等……

  開始自己實現這個功能后,發現寫的代碼比較繁瑣,if語句太多。后面看了opencv的例程后,感覺它的代碼效率非常高。下面就是用來練習下的。

  環境:opencv2.3.1+vs2010

  功能:打開攝像頭,捕捉視頻圖像,用鼠標選定視頻區域(支持各種選擇習慣)。

  代碼和注釋如下:

 1 #include "stdafx.h"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/core/core.hpp>
 5 #include <stdio.h>
 6 #include <iostream>
 7 
 8 using namespace cv;
 9 using namespace std;
10 Rect select;
11 bool select_flag=false;
12 Point origin;
13 Mat frame;
14 
15 /************************************************************************************************************************/
16 /****                    如果采用這個onMouse()函數的話,則只能畫出從左上到右下,或者從右下到左上的矩形框                    ****/
17 /************************************************************************************************************************/
18 //void onMouse(int event,int x,int y,int,void*)
19 //{
20 //    if(event==CV_EVENT_LBUTTONDOWN)
21 //    {
22 //        select.x=x;
23 //        select.y=y;
24 //        tracking=false;
25 //    }
26 //    else if(event==CV_EVENT_LBUTTONUP)
27 //    {
28 //        select.width=x-select.x;//以下2行計算出來的值要么都大於0,要么都小於0
29 //        select.height=y-select.y;
30 //        tracking=true;//左鍵完后,開始跟蹤
31 //    }
32 //}
33 
34 /************************************************************************************************************************/
35 /****                            如果采用這個onMouse()函數的話,則可以畫出鼠標拖動矩形框的4種情形                        ****/
36 /************************************************************************************************************************/
37 void onMouse(int event,int x,int y,int,void*)
38 {
39     //Point origin;//不能在這個地方進行定義,因為這是基於消息響應的函數,執行完后origin就釋放了,所以達不到效果。
40     if(select_flag)
41     {
42         select.x=MIN(origin.x,x);//不一定要等鼠標彈起才計算矩形框,而應該在鼠標按下開始到彈起這段時間實時計算所選矩形框
43         select.y=MIN(origin.y,y);
44         select.width=abs(x-origin.x);//算矩形寬度和高度
45         select.height=abs(y-origin.y);
46         select&=Rect(0,0,frame.cols,frame.rows);//保證所選矩形框在視頻顯示區域之內
47     }
48     if(event==CV_EVENT_LBUTTONDOWN)
49     {
50         select_flag=true;//鼠標按下的標志賦真值
51         origin=Point(x,y);//保存下來單擊是捕捉到的點
52         select=Rect(x,y,0,0);//這里一定要初始化,寬和高為(0,0)是因為在opencv中Rect矩形框類內的點是包含左上角那個點的,但是不含右下角那個點
53     }
54     else if(event==CV_EVENT_LBUTTONUP)
55     {
56         select_flag=false;
57     }
58 }
59 
60 int main(int argc, unsigned char* argv[])
61 {
62     char c;
63 
64     //打開攝像頭
65     VideoCapture cam(0);
66     if (!cam.isOpened())
67         return -1;
68 
69     //建立窗口
70     namedWindow("camera",1);//顯示視頻原圖像的窗口
71 
72     //捕捉鼠標
73     setMouseCallback("camera",onMouse,0);
74 
75     while(1)
76     {
77         //讀取一幀圖像
78         cam>>frame;
79         if(frame.empty())
80             return -1;
81 
82         //畫出矩形框
83         rectangle(frame,select,Scalar(255,0,0),3,8,0);//能夠實時顯示在畫矩形窗口時的痕跡
84 
85         //顯示視頻圖片到窗口
86         imshow("camera",frame);
87 
88     //    select.zeros();
89         //鍵盤響應
90         c=(char)waitKey(20);
91         if(27==c)//ESC鍵
92             return -1;
93     }
94 
95     return 0;
96 }

  可以看出,程序中的select_flag使用得很巧。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM