本文所涉程序为毛星云/冷雪飞等编著的《OpenCV3编程入门》中所写例程,仅为记录本人学习中所碰到的问题与对程序的理解。
先在.pro文件中声明如下变量
INCLUDEPATH +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\include
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingCVw\bin\libopencv_core411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_highgui411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_imgproc411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_calib3d411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_imgcodecs411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_videoio411.dll
LIBS +=D:\Opencv\OpenCV-MinGW-Build-OpenCV-4.1.1-x64\x64\mingw\bin\libopencv_video411.dll
//以上放在.pro文件原有代码的最后就好,前面的路径根据自己安装位置不同而改变
所涉程序如下
#include <opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "[程序窗口]"
//全局函数声明部分
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle( cv::Mat& img, cv::Rect box );
void ShowHelpText();
//全局变量声明部分
Rect g_rectangle;
bool g_bDrawingBox = false;
RNG g_rng(12345);//随机数产生器
int main( int argc, char** argv)
{
g_rectangle = Rect(-1,-1,0,0);//这四个参数的分别代表矩形的左上X,Y坐标和宽度,高度
Mat srcImage(600, 800,CV_8UC3), tempImage;//参考[link]( http://blog.csdn.net/maweifei/article/details/51221259).
//CV_(S|U|F)C
//其中,(1) bit_depth---比特数---代表8bite\16bite\32bite\64bite
//eg:8表示你所创建的储存图片的Mat对象中,每个像素点在内存空间所占的空间大小8bite。
//(2) S|U|F
//S: signed int,即有符号整型;
//U: unsigned int,即无符号整型;
//F: float,单精度浮点型。
//(3) C:所存储的图片的通道数。
//eg 1---grayImg灰度图像---是---单通道图像
//2---RGB彩色图像---是---3通道图像
//3---带Alpha通道的RGB彩色图像---是---4通道图像
srcImage.copyTo(tempImage);//image.copyTo(imageROI),作用是把image的内容粘贴到imageROI
g_rectangle = Rect(-1,-1,0,0);
srcImage = Scalar::all(0);//scalar所有元素设置为0,此时为全黑
//设置鼠标操作回调函数
namedWindow( WINDOW_NAME );
//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:传给回调函数的参数
setMouseCallback( WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
//程序主循环,当绘制的标识符为真时,进行绘制
while(1)
{
srcImage.copyTo(tempImage);//复制源图到临时变量
if( g_bDrawingBox ) DrawRectangle( tempImage, g_rectangle );//当绘制的标识符为真时,则进行绘制
imshow( WINDOW_NAME, tempImage );
if( waitKey( 10 ) == 27 ) break;//waitkey:图像刷新率。27:esc的Ascii码。按下esc键,程序退出
}
return 0;
}
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*) param;//Mat, copy传递,不会改变外部变量的Mat。
//Mat &, reference传递,函数内部修改将会改变外部。
//const Mat, copy传递,在函数内,不会被修改,也不会影响到外部的变量。
//const Mat &, reference传递,确保在函数内外,都不会被修改。
switch( event)//鼠标事件们
{
case EVENT_MOUSEMOVE:
{
if( g_bDrawingBox )//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
{
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;//置标识符为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;
}
}
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)));//随机颜色。tl:top&left。br:bottom&right。
}
参数:
event并不是一个简单的我们自定义的int形式的变量名,而是CV_EVENT_变量之一,一般为setMouseCallBack传过来固定数据,常用的几个数据为:EVENT_MOUSEMOVE(鼠标移动)
EVENT_LBUTTONDOWN (左键按下)
EVENT_RBUTTONDOWN (右键按下)
EVENT_LBUTTONUP (左键弹起)
EVENT_RUTTONUP (右键弹起)
x为鼠标当前所在位置的x坐标。
y为鼠标当前所在位子的y坐标
flags为标志位
用来接收setMouseCallback传递过来的用户数据,为空指针类型。
例如:`void on_MouseHandle(int event, int x, int y, int flags, void param){
Mat& image = (cv::Mat)param;//强行转为mat指针,然后读取其中的内容(因为传递过来的参数为空指针类型,不能直接使用)
switch (event){//event根据鼠标不同的操作传递不同的值过来。然后根据这些值进行不同的操作
case EVENT_MOUSEMOVE://如果鼠标动了
{………….}break;
case EVENT_MOUSEMOVE:
{………….}break;
case EVENT_LBUTTONDOWN :
{………….}break;
case EVENT_RBUTTONDOWN :
{………….}break;
case EVENT_LBUTTONUP :
{………….}break;
case EVENT_RUTTONUP :
{………….}break;
DrawRectangle(Pen, Rectangle)
功能:绘制由 Rectangle 结构指定的矩形。
参数:
第一个参数Pen,它确定线条的颜色、宽度和样式。
第二个参数Rectangle,表示要绘制的矩形的 Rectangle 结构。