我和opencv 4 鼠标交互

来源:互联网 发布:蜜蜡和琥珀哪个贵 知乎 编辑:程序博客网 时间:2024/05/17 05:12

首先是关于opencv的坐标系:
Mat类:和数组一样,原点在左上,竖直为x,水平为y

bool matrix_debug(){    uchar m[9]={0,1,2,3,4,5,6,7,8};    Mat A(3,2,CV_8UC1,m);    cout<<A<<endl;    printf("%d",A.at<uchar>(2,0));    return 1;}

产生一个600*800的窗口

src=Mat(600,800,CV_8UC3,Scalar::all(0));

但是rect类和mat不一样,比如取上述窗口的四个角的坐标,依次为:左上(0,0)、右上(800,0),右下(800,600),左下(0,600),和mat类坐标正好相反。
rectangle函数的理解:

Mat A(600,800,CV_8UC3,Scalar(255,255,255));int i;for(i=1;i<4;i++){    Rect B(0+i*20,0,300+i*20,400);    rectangle(A,B.tl(),B.br(),Scalar(g_rng.uniform(0,256),g_rng.uniform(0,256),g_rng.uniform(0,256)));}imshow("2",A);

该函数可以理解为一张简单的图片,可以由无数个矩形组成,因为每次矩形平移后,都没有消除原先的矩形,而是在后面添加。
大神的源代码消化之后:

//鼠标交互全局变量Mat src,tempImage;Rect g_rectangle;bool g_Drawing=0;RNG g_rng;void on_MouseHandle(int event,int x,int y,int flags,void* param){    Mat& image=*(Mat*) param;    switch(event)    {        case EVENT_MOUSEMOVE:        {            if (g_Drawing)//记录长和宽            {                g_rectangle.width=x-g_rectangle.x;//当前坐标减去鼠标左键按下时的坐标,时时更新                g_rectangle.height=y-g_rectangle.y;            }        }        break;        case EVENT_LBUTTONDOWN://左键按下        {            g_Drawing=1;            g_rectangle=Rect(x,y,0,0);//记录鼠标此时的坐标        }        break;        case  EVENT_LBUTTONUP://左键抬起,画矩形        {            g_Drawing=0;            //DrawRectangle(image,g_rectangle);            //没有下一条语句,左键抬起后矩形会消失,因为没有变量传递给src,src为初始状态,再复制给temp。            rectangle(image,g_rectangle.tl(),g_rectangle.br(),Scalar(g_rng.uniform(0,256),g_rng.uniform(0,256),g_rng.uniform(0,256)));        }        break;    }}//鼠标交互程序bool MouseInteraction(){    g_rectangle=Rect(-1,-1,0,0);//TopLeft,BottomRight    src=Mat(600,800,CV_8UC3,Scalar::all(0));    //src.copyTo(tempImage);    namedWindow("2");    setMouseCallback("2",on_MouseHandle,(void*)&src);//第3个参数用于读取回调函数中的数据    while(1)    {        src.copyTo(tempImage);        if(g_Drawing)//当鼠标左键不抬起的时候总是显示矩形,闪烁表明一直在执行语句        //DrawRectangle(tempImage,g_rectangle);            rectangle(tempImage,g_rectangle.tl(),g_rectangle.br(),Scalar(g_rng.uniform(0,256),g_rng.uniform(0,256),g_rng.uniform(0,256)));    //  cout<<g_rectangle.tl()<<endl;        imshow("2",tempImage);        if(waitKey(10)==27) break;    }    return 1;}int main(){    if(MouseInteraction())        cout<<"success"<<endl;    waitKey(0);    return 0;}
0 0