机器视觉学习笔记(10)——使用鼠标获取像素点信息

来源:互联网 发布:淘宝定时上架什么意思 编辑:程序博客网 时间:2024/06/16 03:38

机器视觉学习笔记(10)——使用鼠标获取像素点信息

标签: 机器视觉


1.目标

使用鼠标对关键点BGR进行采集,采集的数据有正数据和负数据,正数据是需要收集的数据,使用鼠标左键采集,采集后用绿色的圆圈表示;负数据是摈弃的数据,使用鼠标右键采集,采集后用红色的圆圈表示。

2.代码实现

主要通过OpenCV中的回调函数实现,采集的数据存储在data.txt中。需要注意的是,窗口横轴为X轴,竖轴为Y轴,坐标是(x, y),而矩阵坐标是按照(row, col),故窗口中的点(x, y)对应的值在矩阵中为(y, x)

void mouseHandler(int event, int x,int y ,int flags,void *p)  {      Mat img0(*(Mat*)p);      static  Mat img1= img0.clone();//不改变源图像,并且能够显示已标记的点    if(event==CV_EVENT_LBUTTONDOWN)//鼠标左键按下,正数据    {          Point point(x, y);        circle(img1, point, 3, Scalar(0, 255, 0));        //记录数据,显示img1,数据却从原始图像采集,窗口的x, y轴和图像的行和列相反        ofstream file("data.txt", fstream::out | fstream::app);        int b = img0.at<Vec3b>(y, x)[0];        int g = img0.at<Vec3b>(y, x)[1];        int r = img0.at<Vec3b>(y, x)[2];        file<<b<<","<<g<<","<<r<<","<<"1"<<endl;        cout<<b<<","<<g<<","<<r<<","<<"0"<<endl;        //显示图像        imshow("CollectSamplePoints",img1);    }     else if (event==CV_EVENT_RBUTTONDOWN)//鼠标右键按下,负数据    {        Point point(x, y);        circle(img1, point, 3, Scalar(0, 0, 255));        //记录数据        ofstream file("data.txt", fstream::out | fstream::app);        int b = img0.at<Vec3b>(y, x)[0];        int g = img0.at<Vec3b>(y, x)[1];        int r = img0.at<Vec3b>(y, x)[2];        file<<b<<","<<g<<","<<r<<","<<"0"<<endl;        cout<<b<<","<<g<<","<<r<<","<<"0"<<endl;        //显示图像        imshow("CollectSamplePoints",img1);    }} void collect_sample_points(string fileName){    Mat img = imread(fileName);    namedWindow("CollectSamplePoints");    cvSetMouseCallback("CollectSamplePoints", mouseHandler, (void*)&img);    mouseHandler(0, 0, 0, 0, &img);    imshow("CollectSamplePoints", img);    waitKey();}

采集了几个点,效果如下:

3.拓展

通过代码可以发现,鼠标事件通过枚举变量来区分,那么我们右键查看一下定义,看看都有哪些枚举变量。

enum{    CV_EVENT_MOUSEMOVE      =0,//移动    CV_EVENT_LBUTTONDOWN    =1,//左键按下    CV_EVENT_RBUTTONDOWN    =2,//右键按下    CV_EVENT_MBUTTONDOWN    =3,//中键按下    CV_EVENT_LBUTTONUP      =4,//左键弹起    CV_EVENT_RBUTTONUP      =5,//右键弹起    CV_EVENT_MBUTTONUP      =6,//中键弹起    CV_EVENT_LBUTTONDBLCLK  =7,//左键点击    CV_EVENT_RBUTTONDBLCLK  =8,//右键点击    CV_EVENT_MBUTTONDBLCLK  =9 //中键点击};

鼠标事件一共有10个,其实还有双击事件,不过这里并没有提供相应的枚举变量。

试想如果想要在窗口上面画一个矩形,是一个什么过程?左键按下->移动->左键弹起。
那么回调函数中需要做3个判断分支,分别表示这些事件发生

  • 左键按下分支:记录矩形起点
  • 鼠标移动分支:画出起点到当前点的矩形
  • 左键弹起分支:结束画矩形,起点清零

4.总结

  • 使用鼠标在窗口中对图像进行操作通过OpenCV在该窗口下的回调函数实现
  • 可以通过OpenCV提供的事件枚举变量任意组合自己想要的功能
  • 如果不想改变源图像,常常深拷贝一份数据来操作
  • 窗口坐标与其对应的矩阵坐标刚好是相反的
  • 在MFC和Qt中可以利用控件的特性来实现
0 0
原创粉丝点击