• OpenCV图像处理学习七,利用回调函数setMouseCallback和鼠标响应处理函数onMouse实现ROI感兴趣区的提取


    ROI感兴趣区的提取方法

    使用line,ellipse,ellipse,rectangle,fillPoly等函数绘制线、矩形、圆、椭圆等基本图形提取感兴趣区域

    ROI感兴趣区的提取方法——鼠标操作提取方法

    我们通过鼠标交互地提取ROI。OpenCV中鼠标操作依赖鼠标的回调函数响应函数实现。主函数中调用鼠标的回调函数,将鼠标操作与程序的窗口绑定,产生鼠标操作时回调函数调用鼠标响应函数执行。

    回调函数setMouseCallback

    1. void setMouseCallback( const string& winname,
    2.                          MouseCallback onMouse,
    3.                          void* userdata=0 )

    Parameters:  

    第一个参数winname,windows视窗名称,对名为winname的视窗进行鼠标监控;  

    第二个参数onMouse,鼠标响应处理函数,监听鼠标的点击,移动,松开,判断鼠标的操作类型,并进行响应的函数处理;  

    第三个参数 userdata,鼠标响应处理函数的ID,与鼠标相应处理函数相匹配就行,暂时只用到默认为0的情况。

    鼠标响应处理函数onMouse 

    OpenCV中,鼠标相应处理函数一般默认形参和返回参数。

    void onMouse(int event,int x,int y,int flags,void *ustc)

    Parameters:
    第一个参数event,鼠标操作时间的整数代号,在opencv中,event鼠标事件总共有10中,从0-9依次代表如下:

    1. EVENT_MOUSEMOVE       =0,    //滑动  
    2. EVENT_LBUTTONDOWN    =1,    //左键点击  
    3. EVENT_RBUTTONDOWN    =2,    //右键点击  
    4. EVENT_MBUTTONDOWN    =3,    //中间点击  
    5. EVENT_LBUTTONUP        =4,    //左键释放  
    6. EVENT_RBUTTONUP        =5,    //右键释放  
    7. EVENT_MBUTTONUP        =6,    //中间释放  
    8. EVENT_LBUTTONDBLCLK   =7,    //左键双击  
    9. EVENT_RBUTTONDBLCLK   =8,    //右键双击  
    10. EVENT_MBUTTONDBLCLK   =9     //中间释放

    第二个参数x,代表鼠标位于窗口的(x,y)坐标位置,窗口左上角默认为原点,向右为x轴,向下为y轴;
    第三个参数y,代表鼠标的拖拽事件,以及键盘鼠标联合事件,总共有32种事件,这里不再赘述。
    第四个参数flags,函数参数的编号。

    ========================================================================= 

    代码实现:

    1. #include"stdafx.h"
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace cv;
    7. using namespace std;
    8. Point startp(-1, -1);
    9. Point endp(-1, -1);
    10. //绘制圆,需要中心坐标和半径
    11. Point centerp(-1, -1);
    12. int radius = 0;
    13. Mat temp;
    14. void MouseDraw(int event, int x, int y, int flag, void* usedata) {
    15. Mat image = *((Mat*)usedata);
    16. Mat roi;
    17. if (event == EVENT_LBUTTONDOWN) {//左键按下
    18. centerp.x = x;
    19. centerp.y = y;
    20. cout << "center point: " << centerp << endl;
    21. }
    22. else if (event == EVENT_MOUSEMOVE) {//鼠标移动
    23. if ((centerp.x > 0 )& (centerp.y > 0)) {
    24. //得有这个判断条件,不然一开始 不按下鼠标左键时就已经有起始点了
    25. endp.x = x;
    26. endp.y = y;
    27. int w = endp.x - centerp.x;
    28. int h = endp.y - centerp.y;
    29. radius = (int)sqrt(pow(w, 2) + pow(h, 2));
    30. temp.copyTo(image);
    31. //矩形可利用rectangle来实现
    32. circle(image, centerp, radius, Scalar(0, 0, 255), 2);
    33. namedWindow("mousedrawing", 0);
    34. resizeWindow("mousedrawing", 350, 350);
    35. imshow("mousedrawing", image);
    36. }
    37. }
    38. else if (event == EVENT_LBUTTONUP) {//左键抬起
    39. endp.x = x;
    40. endp.y = y;
    41. int w = endp.x - centerp.x;
    42. int h = endp.y - centerp.y;
    43. radius = (int)sqrt(pow(w, 2) + pow(h, 2));
    44. circle(image, centerp, radius, Scalar(0, 0, 255), 2);
    45. namedWindow("mousedrawing", 0);
    46. resizeWindow("mousedrawing", 350, 350);
    47. imshow("mousedrawing", image);
    48. //截取该部分图像
    49. //先截取矩形的部分,再用模取出圆形
    50. Rect rec;
    51. rec.x = centerp.x - radius;
    52. rec.y = centerp.y - radius;
    53. rec.width = 2 * radius;
    54. rec.height = 2 * radius;
    55. Mat Rec_roi = image(rec);//矩形的ROI区域
    56. Mat roi = Mat::zeros(Rec_roi.size(), Rec_roi.type());
    57. roi = Scalar(255, 255, 255);//将目标ROI背景置白
    58. //利用mask提取圆形的ROI
    59. Mat mask = Mat::zeros(Rec_roi.size(), Rec_roi.type());
    60. circle(mask, Point(radius, radius), radius, Scalar(255, 255, 255), -1);
    61. cvtColor(mask, mask, COLOR_BGR2GRAY);
    62. namedWindow("mask", 0);
    63. resizeWindow("mask", 350, 350);
    64. imshow("mask", mask);
    65. Rec_roi.copyTo(roi, mask);
    66. namedWindow("ROI", 0);
    67. resizeWindow("ROI", 350, 350);
    68. imshow("ROI", roi);
    69. //清空中心坐标,这样才会停止掉这一次的绘制
    70. centerp.x = -1;
    71. centerp.y = -1;
    72. }
    73. }
    74. int main(int argc, char*argv) {
    75. Mat image = imread("F:/photo/c.jpg",-1);
    76. namedWindow("mousedrawing",0);
    77. setMouseCallback("mousedrawing", MouseDraw, &image);
    78. resizeWindow("mousedrawing", 350, 350);
    79. imshow("mousedrawing", image);
    80. temp = image.clone();
    81. waitKey(0);
    82. destroyAllWindows();
    83. return 0;
    84. }

     =========================================================================

    图像处理效果

     

  • 相关阅读:
    设计模式学习笔记(十三)组合模式及其在树形结构中的应用
    Gradle系列——Gradle插件(基于Gradle文档7.5)day3-2
    MYSQL
    哈希及哈希表的实现
    NVIDIA Jetson Xavier CAN 开机启动及应用编程
    第四章 文件管理 二、文件的逻辑结构
    RISC-V架构下 FPU Context 的动态保存和恢复
    解密 JavaScript 中的 this:作用、行为和陷阱
    java计算机毕业设计深州市特色蜜桃产业电子商务系统源程序+mysql+系统+lw文档+远程调试
    点集合的三角剖分
  • 原文地址:https://blog.csdn.net/weixin_44651073/article/details/126291080