• 视频标注工具


    视频标注工具

    由于实验室里面需要做CDVA的标准,CDVA(compact descriptor for video analysis),主要是基于CDVS中的紧凑视觉描述子来做视频分析,之前是紧凑视觉描述子主要应用在图像检索领域。需要制作新的数据集,对视频帧进行标注,所以根据网上一个博主的标注工具进行了一定的修改,实现的功能是在每一帧中将需要标注的区域用鼠标选取4个点,顺序是顺时针。因为四边形的范围更广,之前的一些人直接标注了矩形,但是在一些仿射变换中,往往矩形的定位效果不好,矩形定位应该比较适合于人脸定位和行人定位之中。

    这些代码都是基于openCV的,因此在工程配置的时候需要天机opencv的库路径和头文件路径。
    这里简单的介绍一下这个工具的用法

    • 首先运行这个应用程序可以看到一个黑框和一个Video窗口
    • 选取需要标注的区域,按照顺时针,画出4个点(此工具的写的时候默认是每帧图像画一个,不考虑多个情况,如果你要标注多个,就可以添加一个数组存取每个四边形的区域
    • 在画的时候若是点错了地方需求进一步修正则按 'z'即可,按下‘z’可以回退一个点,若画完4个点感觉还是不满意,也可以直接按下'c'全部清除
    • 当确定矩形区域之后,按下‘n’,就会将这些数据写入到指定的txt文件中,同时将进入下一帧
    • 由于视频中连续帧的变化不好,特别是镜头停止的时候,因此,为了避免重复画目标区域,上一帧的四边形坐标会自动的画在下一帧中,若需要重新画,按下‘c’,即可,若不需要重新画,按下'n'即会写入文件,同时继续下一帧,如此往复

    在写入的txt文件中,一行代表一帧中的数据,第一个数为帧数,后4个数,分别是画矩形时依次点入的4个坐标值。
    你可以根据自己的需求,修改这份代码,希望对大家能有所帮助。

    /********************************************************************
        created:	2015/04/18
        created:	18:4:2015   17:24
        filename: 	D:WorkSpaceVS_ProjectsVideoLabelVideoLabel_Quadrilateralvideo_label_quadrilateral.cpp
        file path:	D:WorkSpaceVS_ProjectsVideoLabelVideoLabel_Quadrilateral
        file base:	video_label_quadrilateral
        file ext:	cpp
        author:		Yihang Lou
        purpose:	draw the quadrilateral labels in the frame captured from video
    *********************************************************************/
    #include "opencv2/opencv.hpp"
    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    using namespace std;
    using namespace cv;
    
    // Global variables
    
    Mat img_original, img_drawing;
    Point quad [4];
    //the value of pointNum is between 0~4
    static int pointNum = 0;
    /*************************************************
    // Method: help
    // Description: describe the usage
    // Author: Yihang Lou
    // Date: 2015/04/18
    // Returns: void
    // History:
    *************************************************/
    static void help()
    {
        cout << "This program designed for labeling video 
    "
                "Only if you press the 'n' the present quadrilateral data will be written into txt file
    ";
    
    
            cout << "Hot keys: 
    "
            "	ESC - quit the program
    "
            "	n - next frame of the video
    "
            "	z - undo the last label point 
    "
            "	c - clear all the labels
    "
            << endl;
    }
    /*************************************************
    // Method: drawQuadri
    // Description: 
    // Author: Yihang Lou 
    // Date: 2015/04/18
    // Returns: void
    // Parameter: quad the point of Point array
    // History:
    *************************************************/
    static void drawQuadri (Point * quad) {
        for(int i = 0; i < 4; i++)
        {
            line(img_drawing,quad[i],quad[(i+1)%4],Scalar(0,255,0),1,8,0);
        }
    }
    
    
    /*************************************************
    // Method: onMouse
    // Description: do the actions after onMouse event is called
    // Author: Yihang Lou 
    // Date: 2015/04/18
    // Returns: void
    // Parameter: event
    // Parameter: x Mouse's coordinate
    // Parameter: y 
    // History:
    *************************************************/
    static void onMouse(int event, int x, int y, int, void*)
    {
    
    
        switch (event)
        {
        case CV_EVENT_LBUTTONDOWN:
            quad[pointNum%4].x = x;
            quad[pointNum%4].y = y;
            cout<<"x = "<<x<<" y = "<<y<<endl;
            pointNum++;
    
            break;
        case CV_EVENT_LBUTTONUP:
            //finish drawing the rect (use color green for finish)
    
            circle(img_drawing,cvPoint(x,y),1,Scalar(0, 255, 0),1,8,0);
    
            if(pointNum == 4)
            {
                pointNum = 0;
    
                cout<<"draw quadri line"<<endl;
                drawQuadri(quad);
            }
    
            break;
        }
    
        imshow("Video", img_drawing);
        return;
    }
    
    /*************************************************
    // Method: isempty
    // Description: check the quad is empty
    // Author: Yihang Lou 
    // Date: 2015/04/18
    // Returns: int
    // Parameter: quad
    // History:
    *************************************************/
    int isempty(Point * quad)
    {
        for (int i = 0 ; i < 4; i++)
        {
            if (quad[i].x !=0 || quad[i].y !=0 )
            {
                return 0;
            }
        }
        return 1;
    }
    int main(){
        namedWindow("Video");
        ofstream outfile("1.txt");
        help();
        VideoCapture capture("1.avi");
        capture >> img_original;
        img_original.copyTo(img_drawing);
        imshow("Video", img_original);
        setMouseCallback("Video", onMouse, 0);
        int frame_counter = 0;
        while (1){
            int c = waitKey(0);
            if ((c & 255) == 27)
            {
                cout << "Exiting ...
    ";
                break;
            }
            switch ((char)c)
            {
            case 'n':
                //read the next frame
                ++frame_counter;
                capture >> img_original;
                if (img_original.empty()){
                    cout << "
    Video Finished!" << endl;
                    return 0;
                }
    
                img_original.copyTo(img_drawing);
    
                if (!isempty(quad))
                {
                    drawQuadri(quad);
    
                    outfile << frame_counter << " " << quad[0].x << " "<< quad[0].y << " " 
                        << quad[1].x << " "<< quad[1].y << " "
                        << quad[2].x << " "<< quad[2].y << " "
                        << quad[3].x << " "<< quad[3].y << " "<<endl;
                }
    
                break;
            case 'z':
                //undo the latest labeling point
                if(pointNum == 0)
                {
                    cout<<"if you want to clear the existent quad please press 'c'"<<endl;
                    break;
                }
                pointNum--;
                quad[pointNum].x=0;
                quad[pointNum].y=0;
                img_original.copyTo(img_drawing);
                for(int i = 0 ; i < pointNum; i++)		
                {
                    circle(img_drawing,quad[i],1,Scalar(0, 255, 0),1,8,0);
                }
    
                break;
            case 'c':
                //clear quad array
                memset(quad,0,4*sizeof(Point));
                img_original.copyTo(img_drawing);
            }
            imshow("Video", img_drawing);
        }
    
        return 0;
    }
  • 相关阅读:
    数型DP
    士兵杀敌(三)(RMQ)(DP) or ( 线段树 )
    还是回文
    dp(DAG)
    mysql的内连接外连接查询
    一些概念
    函数式编程中的一些概念
    Optional<T>
    计算文件和字符串的MD5摘要
    SpringMVC的一些配置
  • 原文地址:https://www.cnblogs.com/louyihang-loves-baiyan/p/4457462.html
Copyright © 2020-2023  润新知