您的位置:首页 > 运维架构

基于opencv视频中运动目标标定

2016-12-16 18:06 302 查看
//Tools for Labeling Video 

#include <opencv2/opencv.hpp>

#include <iostream>

#include <string>

#include <vector>

#include <fstream>

using namespace std;

using namespace cv;

struct labelRect

Rect rect;
int label; 
};

// Global variables

bool bGlobalDragBox2 = 0;                 ///<满足条件:按下右键,鼠标起点在box内、拖动 

bool is_drawing=false;  

vector<labelRect> frameLabelBoxs;         ///<当前帧的标注矩形框

vector<labelRect> preFrameLabelBoxs;       ///<上一次标注矩形框

labelRect labelBox;                        ///<当前帧某一个标注

labelRect globalLabelBox;                  ///<左键画框

Rect drawing_box; 

int globalDragIndex=0;                      ///<右键选中框索引

Mat img_original,img_drawing, preFrame ;

Mat tmpMat;                                 ///<用于实时显示

int globalLabel=0;                          ///<标注的id

static void help()
{
cout << "This program designed for labeling video \n" ; 
cout<<"Use the mouse  left button  to draw rectangle on the image for labeling.\n"<<endl;  
cout<<"Use the mouse  right button to drag rectangle on the image  .\n"<<endl; 

cout<<"parameter instructions :para1 is video file ,para2 is label save file\n"
"\tn,example:labelVideo t.avi t.txt "<<endl;

cout << "Hot keys: \n"
"\tESC - quit the program\n"
"\tn - next frame of the video\n"
"\tu - undo the last label\n"
"\tc - clear all the labels\n"

"\td - delete select drag rectangle\n"

"\t+ - increase select drag rectangle\n"
"\t- - decrease select drag rectangle\n"

<<endl;
}

static void onMouse( int event, int x, int y, int flags, void* )
{
static Point pre_pt = (-1,-1);//初始坐标  
static Point cur_pt = (-1,-1);//实时坐标  
static CvPoint mv_pt = {-1,-1}; 
static CvPoint dragStart_pt = {-1,-1}; //拖动矩形起、终点
static CvPoint dragEnd_pt = {-1,-1};  

CvFont font;  
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);//初始化字体  
char temp[16]; 

switch(event)
{
case CV_EVENT_LBUTTONDOWN: 
//the left up point of the rect  

for(vector<labelRect>::iterator it=frameLabelBoxs.begin();  it!=frameLabelBoxs.end(); ++it) 
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0)); 
sprintf(temp,"%d",(*it).label);  
putText(img_drawing,temp, Point((*it).rect.x ,(*it).rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  

}

bGlobalDragBox2=0;
pre_pt = Point(x,y);  
is_drawing=true; 
drawing_box.x=x;
drawing_box.y=y;  

break;

case CV_EVENT_MOUSEMOVE:
//adjust the rect (use color blue for moving) 
for(vector<labelRect>::iterator it=frameLabelBoxs.begin();  it!=frameLabelBoxs.end(); ++it) 
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0)); 
sprintf(temp,"%d",(*it).label);  
putText(img_drawing,temp, Point((*it).rect.x ,(*it).rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  

}

if(is_drawing)
{
drawing_box.width=x-drawing_box.x;
drawing_box.height=y-drawing_box.y;
img_original.copyTo(img_drawing);
/*for(vector<labelRect>::iterator it=frameLabelBoxs.begin();
it!=frameLabelBoxs.end();++it)
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0));
}*/
rectangle(img_drawing,drawing_box,Scalar(255,0,0));


// img_drawing.copyTo(tmpMat);
break;

case CV_EVENT_LBUTTONUP:
//finish drawing the rect (use color green for finish)
if(is_drawing)
{
drawing_box.width=x-drawing_box.x;
drawing_box.height=y-drawing_box.y;
img_original.copyTo(img_drawing);  
globalLabel++;
//!画第1,2,...,n-1个标注
for(vector<labelRect>::iterator it=frameLabelBoxs.begin();  it!=frameLabelBoxs.end(); ++it) 
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0)); 
sprintf(temp,"%d",(*it).label);  
putText(img_drawing,temp, Point((*it).rect.x ,(*it).rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  

}

//!第n个目标标注
rectangle(img_drawing,drawing_box,Scalar(0,255,0));  
sprintf(temp,"%d",globalLabel); 
putText(img_drawing,temp, Point(drawing_box.x,drawing_box.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  

globalLabelBox.rect=drawing_box; 
globalLabelBox.label=globalLabel;
frameLabelBoxs.push_back(globalLabelBox);  
}
is_drawing=false;

img_drawing.copyTo(tmpMat);    ///<更新显示,右键拖动的框,否则会连成一片
break; 

case CV_EVENT_RBUTTONDOWN:         ///< 按下鼠标右键   
{  
pre_pt = cvPoint(x,y);         ///< 获取当前点坐标值   

for(int i=0;i<frameLabelBoxs.size();i++)
{
labelBox = frameLabelBoxs[i];
drawing_box=labelBox.rect; 
sprintf(temp,"(%d )",labelBox.label);  ///< 格式化字符串   

//!满足条件移动
if(pre_pt.x>drawing_box.x && pre_pt.x<drawing_box.x+drawing_box.width &&
pre_pt.y>drawing_box.y && pre_pt.y<drawing_box.y+drawing_box.height)
{  
globalDragIndex=i;
}



}  
break;

case CV_EVENT_RBUTTONUP:    ///<鼠标右键弹起   
if(bGlobalDragBox2)
{
drawing_box.x = dragStart_pt.x;
drawing_box.y = dragStart_pt.y;
drawing_box.width=dragEnd_pt.x-dragStart_pt.x;
drawing_box.height=dragEnd_pt.y-dragStart_pt.y;  

sprintf(temp,"%d",frameLabelBoxs[globalDragIndex].label);//格式化字符串   
putText(img_drawing,temp, Point(drawing_box.x,drawing_box.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));   

rectangle(img_drawing,drawing_box,Scalar(0,0,255));
frameLabelBoxs[globalDragIndex].rect = drawing_box;
}

bGlobalDragBox2=0;

break; 

}      ///<switch end

//!鼠标移动并且鼠标右键按下
if( (event == CV_EVENT_MOUSEMOVE) &&  (flags & CV_EVENT_RBUTTONDOWN) ) 
{  

cur_pt = cvPoint(x,y);//获取当前点坐标值  

for(int i=0;i<frameLabelBoxs.size();i++)
{
labelBox = frameLabelBoxs[i];
drawing_box=labelBox.rect; 
sprintf(temp,"(%d )",labelBox.label);//格式化字符串   

//!满足条件移动
if(pre_pt.x>drawing_box.x && pre_pt.x<drawing_box.x+drawing_box.width &&
pre_pt.y>drawing_box.y && pre_pt.y<drawing_box.y+drawing_box.height)
{
bGlobalDragBox2=true; 
mv_pt.x = cur_pt.x - pre_pt.x;
mv_pt.y = cur_pt.y - pre_pt.y; 
dragStart_pt.x = drawing_box.x + mv_pt.x;
dragStart_pt.y = drawing_box.y + mv_pt.y;
dragEnd_pt.x = drawing_box.x+drawing_box.width + mv_pt.x;
dragEnd_pt.y = drawing_box.y +drawing_box.height+ mv_pt.y;

putText(img_drawing,temp, Point(dragStart_pt.x,dragStart_pt.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));   
rectangle(img_drawing, dragStart_pt, dragEnd_pt, cvScalar(0,0,255,0), 2, 8, 0 );//在图像上画矩形 

 
globalDragIndex=i;
}

}

tmpMat.copyTo(img_drawing);

}  

imshow("Video",img_drawing);
return;



int main_(int argc, char * argv[])
{
help();
VideoCapture capture(argv[1]); 
int frameCount =  capture.get(CV_CAP_PROP_FRAME_COUNT);
cout<<"video frame count is :"<<frameCount<<endl;

long frameToStart =2665; 
globalLabel = 8;

capture.set( CV_CAP_PROP_POS_FRAMES,frameToStart); 

capture>>img_original;
img_original.copyTo(img_drawing); 
namedWindow("Video"); 
setMouseCallback( "Video", onMouse, 0 );  

ofstream outfile(argv[2]); 
int iFrameNumber=frameToStart;  
char cTempLabel[20];                ///<显示object label 
int labelFrameInternal=4;

while(1)


if(preFrame.data)

for(vector<labelRect>::iterator it=preFrameLabelBoxs.begin();  it!=preFrameLabelBoxs.end();  ++it) 
{
rectangle(preFrame,(*it).rect,Scalar(0,255,0));
sprintf(cTempLabel,"%d",(*it).label);  
putText(preFrame,cTempLabel, Point((*it).rect.x ,(*it).rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  

imshow("preFrame",preFrame); 
waitKey(10);


int c=waitKey(0);

if( (c & 255) == 27 ) 
{
cout << "Exiting ...\n";
break;
}
switch((char)c)


case 'n':
//read the next frame
++iFrameNumber;
cout<<"save frame number is :"<<iFrameNumber<<endl;  
capture>>img_original;
if(img_original.empty()){return 0;}  
img_original.copyTo(img_drawing); 

//!save  
for(vector<labelRect>::iterator it=frameLabelBoxs.begin();it!=frameLabelBoxs.end();++it) 
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0));  
outfile<<iFrameNumber<<" "<<(*it).label<<" "<<(*it).rect.x<<" "
<<(*it).rect.y<<" "<<(*it).rect.width<<" " <<(*it).rect.height<<endl; 


img_original.copyTo(preFrame); 

for(int i=0;i<labelFrameInternal;i++)
{
++iFrameNumber;
cout<<"skip  frame number is :"<<iFrameNumber<<endl;
capture>>img_original;
if(img_original.empty()){return 0;}  



preFrameLabelBoxs=frameLabelBoxs; 
frameLabelBoxs.clear(); 

for(vector<labelRect>::iterator it=preFrameLabelBoxs.begin();it!=preFrameLabelBoxs.end();++it) 
{
frameLabelBoxs.push_back(*it);
}  

img_original.copyTo(img_drawing);

img_drawing.copyTo(tmpMat);
 
break;

case 'u':
//undo the latest labeling
if(!frameLabelBoxs.empty())
{
vector<labelRect>::iterator it_end=frameLabelBoxs.end();
--it_end;
frameLabelBoxs.erase(it_end);
}

img_original.copyTo(img_drawing);
for(vector<labelRect>::iterator it=frameLabelBoxs.begin();it!=frameLabelBoxs.end();++it) 
{
rectangle(img_drawing,(*it).rect,Scalar(0,255,0));
sprintf(cTempLabel,"%d",(*it).label);  
putText(img_drawing,cTempLabel, Point((*it).rect.x ,(*it).rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  
}

break; 

case 'c':

//clear all the rects on the image
frameLabelBoxs.clear();
img_original.copyTo(img_drawing);
break;

case '+':
{

int increase=5; 
frameLabelBoxs[globalDragIndex].rect.width +=increase;
frameLabelBoxs[globalDragIndex].rect.height +=increase;
break;

}

case '-':
{
int decrease=5; 
frameLabelBoxs[globalDragIndex].rect.width  -= decrease;
frameLabelBoxs[globalDragIndex].rect.height -= decrease;
break;

}

case 'd':    ///!delete 


vector<labelRect>::iterator it;

if(frameLabelBoxs.size()>0)

it = frameLabelBoxs.begin() + globalDragIndex ;   
frameLabelBoxs.erase(it);
}  

break;

}



for(int i=0;i<frameLabelBoxs.size();i++)
{
if(i==globalDragIndex)
rectangle(img_drawing,frameLabelBoxs[i].rect,Scalar(0,0,255)); 
else
rectangle(img_drawing,frameLabelBoxs[i].rect,Scalar(0,255,0)); 
sprintf(cTempLabel,"%d",frameLabelBoxs[i].label);  
putText(img_drawing,cTempLabel, Point(frameLabelBoxs[i].rect.x ,frameLabelBoxs[i].rect.y),FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,255,0,255));  



imshow("Video",img_drawing); 
waitKey(10);
img_original.copyTo(img_drawing);
//img_original.copyTo(preFrame); 

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: