switch(event) {
case CV_EVENT_LBUTTONDBLCLK:{
//g_rect.x = x;
//g_rect.y = y;
g_isPaint = true;
g_rect.x = x;
g_rect.y = y;
cout<<"left button clicked"<<endl;
}
break;
//鼠标移动
case CV_EVENT_MOUSEMOVE: {
if(g_isPaint){
g_rect.width = x - g_rect.x;
g_rect.height = y - g_rect.y;
cout<<"moving"<<endl;
}
}
break;
case EVENT_LBUTTONUP:{
g_isPaint = false;
if(g_rect.width<0){
g_rect.x += g_rect.width;
g_rect.width *= -1;
}
if(g_rect.height<0){
g_rect.y += g_rect.height;
g_rect.height *= -1;
}
cout<<"left button up, about to draw"<<endl;
DrawRectangle(image, g_rect);
}
break;
这么写,发现点击左键事件和移动的事件都没有发生。为什么?
原来= =是事件写错了。第一个不应该是双击左键,而是LBUTTONDOWN。而且DrawRectangle函数并不能放在响应函数里面,我认为是因为image实际上是在main函数里面定义的,所以要在main函数里面被使用?这里不是很清楚。后面把image定义成全局变量,还是只有在main中调用画矩形函数才会真正地画出矩形……
#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
//鼠标响应
void onMouse(int event, int x, int y, int flags, void* param);
//绘制矩形
void DrawRectangle(Mat &img, Rect box);
Rect g_rect;
bool g_isPaint = false;
RNG g_rng(1000);
Mat srcImage1(600,800, CV_8UC1, Scalar(255, 255, 255));
#define WINDOWNAME "Paint"
int main(int argc, char** argv) {
g_rect = Rect(-1, -1, 0, 0);
Mat srcImage1(600,800, CV_8UC1, Scalar(255, 255, 255)), tempImage;
srcImage1.copyTo(tempImage);
namedWindow(WINDOWNAME, WINDOW_AUTOSIZE);
//setMouseCallback的第三个形参本身就是一个指向void类型的指针,现在让这个指针还是一个引用。
setMouseCallback(WINDOWNAME, onMouse, (void*)&tempImage);
waitKey(1);
while(1) {
imshow(WINDOWNAME, tempImage);
if(g_isPaint) {
DrawRectangle(tempImage, g_rect);
}
if(waitKey(1)==32) {
break;
}
}
return 0;
}
void onMouse(int event, int x, int y, int flags, void* param) {
Mat& image = *(Mat*) param;
if(event==EVENT_LBUTTONDOWN) {
//g_rect.x = x;
//g_rect.y = y;
g_isPaint = true;
g_rect.x = x;
g_rect.y = y;
cout << "left button clicked" << endl;
}
else if(event== EVENT_MOUSEMOVE) {
if (g_isPaint==true) {
g_rect.width = x - g_rect.x;
g_rect.height = y - g_rect.y;
cout << "moving" << endl;
}
}
else if(event==EVENT_LBUTTONUP) {
//在这里如果g_isPaint一直是true,主函数会一直调用画矩形函数
g_isPaint = false;
if (g_rect.width < 0) {
g_rect.x += g_rect.width;
g_rect.width *= -1;
}
if (g_rect.height < 0) {
g_rect.y += g_rect.height;
g_rect.height *= -1;
}
cout << "left button up, about to draw" << endl;
//DrawRectangle(image, g_rect);
//复原
g_rect = Rect(-1, -1, 0, 0);
cout<<g_rect.x<<","<<g_rect.y<<","<<g_rect.width<<","<<g_rect.height<<endl;
}
}
void DrawRectangle(Mat &img, Rect box) {
rectangle(img, box.tl(), box.br(), \
Scalar(g_rng.uniform(0, 255) ,g_rng.uniform(0, 255), g_rng.uniform(0, 255)), 1, 1, 0);
waitKey(1);
cout<<box.tl()<<","<<box.br()<<endl;
}
不过这样还会画出来移动过程中的矩形:
所以思考一下怎么样画出跟踪轨迹的,但是过程中又不会被画出来的矩形呐?