问题:
在进行特征学习时,经常需要将大量的图像提取出特征点(关键点),因此,想到在显示图像的时候,使用鼠标的双击操作来确定 关键点的位置。
操作要点:
1显示图像
2鼠标双击事件处理:左键双击,增加鼠标所在的点为新的关键点;右键双击,删除最近添加的关键点,与双击时的鼠标位置无关。
3实时显示:显示最新添加的点
4提取的关键点导出
代码:
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
#define CONFIRM_PT_NUM (20)
struct ConfirmParam {
string window; // 窗口名称
Mat* image;
Point points[CONFIRM_PT_NUM];
int point_idx;
};
void on_mouse_cb_confirm_pt (int event, int x, int y, int flags, void* userdata) {
ConfirmParam* param = (ConfirmParam *) userdata;
Mat display;
param->image->copyTo (display);
switch (event) {
case CV_EVENT_LBUTTONDBLCLK: { // 左键双击:增加点
if (param->point_idx < CONFIRM_PT_NUM) {
param->points[param->point_idx].x = x;
param->points[param->point_idx].y = y;
param->point_idx++;
}
}
break;
case CV_EVENT_RBUTTONDBLCLK: { // 右键双击: 删除最近添加的点
param->point_idx--;
}
break;
default:
break;
}
// 用于实时显示的绘制
for (int i = 0; i < param->point_idx; i++) {
circle (display, param->points[i], 4, CV_RGB (255, 0, 0), -1);
}
//
cv::imshow (param->window, display);
cv::waitKey (1);
}
void main() {
VideoCapture video (700);
if (!video.isOpened()) {
return;
}
while (1) {
Mat frame;
video >> frame;
if (!frame.empty()) {
break;
}
}
//
int frame_idx = 0;
char sz[32] = {0};
ConfirmParam param;
param.window = "CONFIRM";
param.point_idx = 0;
namedWindow (param.window);
//
while (1) {
Mat frame;
video >> frame;
if (frame.empty()) {
break;
}
//
frame_idx++;
//
Mat frame_cpy;
frame.copyTo (frame_cpy);
//
sprintf_s (sz, "frame %d", frame_idx);
putText (frame_cpy, sz, Point (0, 30), CV_FONT_NORMAL, 1.1, CV_RGB (255, 0, 0), 1);
//
//param.window; // 窗口名称
param.image = &frame_cpy;;
//memset (param.points, -1, sizeof (param.points));
param.point_idx = 0;
setMouseCallback (param.window, on_mouse_cb_confirm_pt, ¶m);
imshow (param.window, frame_cpy);
waitKey (0);
// 选中点处理: 写到文件
FILE* fd = fopen ("point.dat", "ab+");
if (fd) {
fprintf (fd, "frame %d:", frame_idx);
for (int i = 0; i < param.point_idx; i++) {
fprintf (fd, " (%4d,%4d)", param.points[i].x, param.points[i].x);
}
fprintf (fd, "\n");
fclose (fd);
}
//
}
}
结果:
Mylaf