通过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();
}
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 //中键点击
};