我和opencv 4 鼠标交互

首先是关于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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值