// OpenCV对鼠标事件的处理
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
/*
1:事件宏定义
enum
{
EVENT_MOUSEMOVE =0,
EVENT_LBUTTONDOWN =1,
EVENT_RBUTTONDOWN =2,
EVENT_MBUTTONDOWN =3,
EVENT_LBUTTONUP =4,
EVENT_RBUTTONUP =5,
EVENT_MBUTTONUP =6,
EVENT_LBUTTONDBLCLK =7,
EVENT_RBUTTONDBLCLK =8,
EVENT_MBUTTONDBLCLK =9
};
2:回调函数的定义方式(函数指针)
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
//! assigns callback for mouse events
CV_EXPORTS void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0);
3:画线函数
line
Draws a line segment connecting two points.
C++: void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
4:画矩形函数
rectangle
Draws a simple, thick, or filled up-right rectangle.
C++: void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
*/
vector<Point> mousePoints;
Point points;
static void onMouse(int event, int x, int y, int, void*)
{
if (event == EVENT_LBUTTONDOWN || event == EVENT_MOUSEMOVE || event == EVENT_RBUTTONDOWN)
{
return;
}
points.x = x;
points.y = y;
mousePoints.push_back(points);
cout << "用户点击图像: 位置 " << x << ": " << y << endl;
}
//输出单击点的GRB值
void on_mouse(int EVENT, int x, int y, int flags, void* userdata)
{
Mat hh;
hh = *(Mat*)userdata;
Point p(x, y);
switch (EVENT)
{
case EVENT_LBUTTONDOWN:
{
printf("b=%d\t", hh.at<Vec3b>(p)[0]);
printf("g=%d\t", hh.at<Vec3b>(p)[1]);
printf("r=%d\n", hh.at<Vec3b>(p)[2]);
circle(hh, p, 2, Scalar(255), 3);
}
break;
}
}
void mouseHandler(int event, int x, int y, int flags, void* param)
{
Point p(x, y);
//p.x = x, p.y = y;
IplImage* img0, *img1;
Mat image;
image = *(Mat*)param;
//img0 = (IplImage*)param;
img0 = &IplImage(image);
img1 = cvCloneImage(img0);
CvFont font;
uchar* ptr;
char label[20];
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, .8, .8, 0, 1, 8);
if (event == CV_EVENT_LBUTTONDOWN) //单击左键
{
/* read pixel */
ptr = cvPtr2D(img1, y, x, NULL);//返回指向特殊数组元素的指针 && cvGet2D返回指向特殊数组的元素
/*display the BGR value*/
sprintf(label, "(%d, %d, %d)", ptr[0], ptr[1], ptr[2]);
//sprintf_s(labels, "(%d, %d, %d)", ptr[0], ptr[1], ptr[2]);
//cvRectangle(img1, cvPoint(x, y - 12), cvPoint(x + 100, y + 4), CV_RGB(255, 0, 0), CV_FILLED, 8, 0);
cvPutText( img1, label, cvPoint(x, y), &font, CV_RGB(255,0,0) );
//putText(image, label, p, 1, 2, CV_RGB(255, 0, 0), 2);
//putText(image, label, Point(x,y), 1, 2, CV_RGB(255, 0, 0), 2);
cout << "用户点击图像: 位置 " << x << ": " << y << endl;
cvShowImage("img", img1);
//imshow("image", image);
}
}
int main()
{
VideoCapture cap(0);
Mat frame;
if (!cap.isOpened())
{
cout << "无法打开视频文件" << endl;
return -1;
}
namedWindow("mouseCallback");
//获得并输出点击处的位置
//setMouseCallback("mouseCallback", onMouse);
//opencv3 获得点击处的像素值
//setMouseCallback("mouseCallback", on_mouse, &frame);
//opencv2 获得点击处的像素值 和点击的位置
cvSetMouseCallback("mouseCallback", mouseHandler, &frame);
while (1)
{
bool bRead = cap.read(frame);
if (!bRead)
{
cout << "视频文件读取完成" << endl;
break;
}
if (mousePoints.size() > 1)
{
mousePoints.clear();
}
for (vector<Point>::iterator it = mousePoints.begin(); it != mousePoints.end(); it++)
{
circle(frame, *it, 5, CV_RGB(255, 0, 0));
}
imshow("mouseCallback", frame);
if (waitKey(10) == 27) break;
}
cap.release();
destroyAllWindows();
}