视频标注工具

来源:互联网 发布:redis 持久化数据库 编辑:程序博客网 时间:2024/06/05 03:59

视频标注工具

由于实验室里面需要做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:\WorkSpace\VS_Projects\VideoLabel\VideoLabel_Quadrilateral\video_label_quadrilateral.cpp    file path:  D:\WorkSpace\VS_Projects\VideoLabel\VideoLabel_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 variablesMat img_original, img_drawing;Point quad [4];//the value of pointNum is between 0~4static 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 \n"            "Only if you press the 'n' the present quadrilateral data will be written into txt file\n";        cout << "Hot keys: \n"        "\tESC - quit the program\n"        "\tn - next frame of the video\n"        "\tz - undo the last label point \n"        "\tc - clear all the labels\n"        << 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 ...\n";            break;        }        switch ((char)c)        {        case 'n':            //read the next frame            ++frame_counter;            capture >> img_original;            if (img_original.empty()){                cout << "\nVideo 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;}
0 0
原创粉丝点击