来自毛星云的opencv3编程入门 自己另外加了一些注释
include
define WINDOW_NAME “【程序窗口】”
void on_MouseHandle(int event, int x, int y, int flags, void* param);//1:传入的消息 2:鼠标此刻所在x坐标 3:鼠标此刻所在y坐标 4:EVENT_FLAG的组合(这是什么东东,) 5:用户想要传递到鼠标中断函数的参数
void DrawRectangle( cv::Mat& img, cv::Rect box );
Rect g_rectangle;//定义一个矩形对象
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345); //定义一个随机函数对象;
int main( int argc, char** argv )
{
g_rectangle = Rect(-1,-1,0,0);//初始化g_rectangle;//定义一个坐标为(-1,-1)的点
Mat srcImage(600, 800,CV_8UC3), tempImage;//大小600X800,8位3通道图像
srcImage.copyTo(tempImage); //将srcImage复制给临时图像tempImage;
srcImage = Scalar::all(0);//Scalar是对矩阵进行初始化赋值,此处则全通道赋值0,所以背景图是黑色;
//【2】设置鼠标操作回调函数
namedWindow( WINDOW_NAME );
setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);//这里除了将窗口和鼠标中断函数绑定在一起外,还使能了鼠标中断函数,每当有鼠标操作事件发生时就进入鼠标中断函数
//【3】程序主循环,当进行绘制的标识符为真时,进行绘制
while(1)//不断等待鼠标事件发生,直到用户自己退出
{
srcImage.copyTo(tempImage);//src.copyTo( dst, detected_edges),是将src中detected_edges矩阵对应的非零部分复制到dst中;
if( g_bDrawingBox )//当按下左键进入画矩形函数
DrawRectangle( tempImage, g_rectangle );//绘制矩形
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_rectangle的信息
{
//鼠标移动的过程中鼠标的坐标(x,y)是在不断的改变的;
g_rectangle.width = x-g_rectangle.x;//传入的x,y即为鼠标当前位置,(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;//松开鼠标停止绘制
if( g_rectangle.width < 0 )//以下对特殊情况处理
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;//若width为负,则取绝对值
}
if( g_rectangle.height < 0 )
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
//调用函数进行绘制
DrawRectangle( image, g_rectangle );//得到了g_rectangle的信息,开始绘制
}
break;
}
}
//———————————–【DrawRectangle( )函数】—————————-
void DrawRectangle( cv::Mat& img, cv::Rect box )
{
cv::rectangle(img,box.tl(),box.br(),cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255)));//tl为左上角坐标,br为右下角坐标,在(Mat)img上绘制和(Rect)box位置一样 大小相同的 随机颜色的矩形,RNG类的uniform函数可以返回指定范围的随机数
}