OpenCV 对图像序列实时可视化标记关键点

问题:

         在进行特征学习时,经常需要将大量的图像提取出特征点(关键点),因此,想到在显示图像的时候,使用鼠标的双击操作来确定 关键点的位置。

         

操作要点:

        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

 

你可能感兴趣的:(OpenCV)