c++ - 在 OpenCV 中使用 MouseCallback 绘图

标签 c++ opencv callback

使用 OpenCV 2.4.3,当用户移动鼠标时,我尝试在以鼠标 (x,y) 位置为中心的图像顶部绘制一个圆圈,一旦鼠标停止,该圆圈就应该在那里移动(此时仅应显示仅绘制一个圆圈的原始图像)。我以为这会很容易,但是,我已经研究和尝试了几个小时,但无法使其按照我描述的方式工作。

我在下面附上了我的代码。如果有人能提供帮助,我将不胜感激。

void my_mouse_callback( int event, int x, int y, int flags, void* param );
bool moving_mouse = false;

int main()
{
const char* name = "Circle Example";

IplImage* image_circle = cvLoadImage( "../data/lena.png" );
IplImage* image = cvLoadImage( "../data/lena.png" );

namedWindow(name, CV_WINDOW_AUTOSIZE );

// Set up the callback
cvSetMouseCallback( name, my_mouse_callback, (void*) image_circle);

//Main Loop
while(cvWaitKey(15) != 27){ 

    //If mouse is moving draw circle on top of image
    if(moving_mouse){
        cvShowImage(name, image_circle);
        moving_mouse = false;
    }
    //If mouse stops moving draw original image and reset image_cicle
    else{
        cvShowImage(name, image);
        image_circle = cvCloneImage(image);
    }
}

cvReleaseImage(&image_circle);
cvReleaseImage(&image);
cvDestroyWindow(name);
return 0;
}


// Mouse callback
void my_mouse_callback( int event, int x, int y, int flags, void* param ){

switch( event ){
    case CV_EVENT_MOUSEMOVE: 
        //Drawing a Circle
        cvCircle(param,cvPoint(x,y),25,CV_RGB(0,255,0),1);
        moving_mouse = true;
        break;

          }
    }

最佳答案

我向您展示了一种实现此目的的方法。稍后我会解释并告诉你你会遇到的困难:

static int mouse_x = -1;
static int mouse_y = -1;

void my_mouse_callback( int event, int x, int y, int flags, void* param )
{
  if(event == CV_EVENT_MOUSEMOVE)
  {
    mouse_x = x;
    mouse_y = y;
  }
}

int main()
{
  IplImage* image;
  IplImage* image_circle = NULL;

  ... // load image, create window, initiate callback, etc

  int x = -1;
  int y = -1;
  while(cvWaitKey(15) != 27)
  { 
    if(x != mouse_x || y != mouse_y)
    {
      x = mouse_x;
      y = mouse_y;

      cvReleaseImage(&image_circle);
      image_circle = cvCloneImage(image);
      cvCircle(image_circle,cvPoint(x,y),25,CV_RGB(0,255,0),1);
      cvShowImage(name, image_circle);
    }
  }

  ... // destroy image
}

说明

这里,在鼠标事件中,您只存储鼠标指针的坐标。当事件发生时,主程序将检查鼠标是否移动以再次重绘完整图像。由于要删除之前的圆,因此必须先复制原始图像,然后再绘制新的圆。您可以通过复制原始图像中前一个圆圈的部分而不是整个图像来使此操作变得更智能。

问题

在 OpenCV 中执行此类操作时的一个问题是,您无法检测到鼠标何时移出窗口,因此您的图像中始终会绘制一个圆圈。我不认为你可以只用 OpenCV 来解决这个问题,因为我不认为有一种 MOUSE_OUT 事件。您需要寻找一些 Qt 回调或系统函数。

关于c++ - 在 OpenCV 中使用 MouseCallback 绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18745302/

相关文章:

python - 使用 cv2.VideoCapture() 从 IP 摄像机读取流

Java简单回调

c++ - 索引 : Implementing Tree data structures with Arrays/Vectors

c++ - vector 相关的内存分配问题

c++ - 将 Vector<float> 中的数据复制到 Vector<Mat> (Opencv/C++)

python - 如何在 Python 中将 DCT 应用于图像?

ruby-on-rails - Ruby - 为什么这个回调函数不起作用

callback - GStreamer:如何连接动态垫

c++ - 如何在我的游戏中执行脚本?

c++ - 获取用户输入以在私有(private)部分 C++ 中定义变量的值