数据标定小工具

来源:互联网 发布:二手丝袜淘宝 编辑:程序博客网 时间:2024/06/05 18:21

为了方便在制作机器学习所需的样本数据,提高工作效率,写了一个简单的矩形框标定并保存标定图像的程序,相关程序可由VS2012+OpenCV2411生成,默认对352*288大小的视频手动进行目标样本截取并保存。

先切换到程序marksave的目录下,需要在目录下分别建立一个叫avi和obj的文件夹,前者放视频,后者存放标定的样本数据,然后在cmd命令行中输入相关参数。

注意输入参数格式依次如下:

第一个输入参数为程序名:marksave.exe

第二个输入参数为视频名:avi/test.avi为视频文件,放置在当前目录下的avi文件夹里;

第三个输入参数控制图像输出格式:1表示会将所截取的图修正为正方形,若取0则不作修正;

第四个输入参数表示起始帧数:10表示从第10帧开始播放;

第五个输入参数表示图片保存格式:0表示存储为*.png1表示存储为*.jpg


程序开始执行后,按键P可以控制视频的暂停/播放;暂停后用鼠标先后点击目标的左上角和有下角确定需要的保存区域,逐个标定完后,再按P继续播放。结果保存在obj文件夹下,第三个输入参数为1时在保存时会对图像比例做修正,使之为正方形。

代码如下,大家可以根据自己的需求做下修改应用到自己的项目上。

// marksave.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <cv.h>#include <highgui.h>#include <math.h>#include <time.h>#include <iostream>#include <fstream>#include <Windows.h>  #define OBJLEN 10//视频图像宽高#define IMGWIDHT 352#define IMGHEIGHT 288using namespace cv;  using namespace std;int objnum = 0;bool pause = false;//是否暂停IplImage *curframe = NULL; //复制原图像IplImage *localframe = cvCreateImage(cvSize(IMGWIDHT,IMGHEIGHT),IPL_DEPTH_8U, 3);bool lineflag = true;//ROI区域两端点坐标int pointl_x[OBJLEN] = {0};int pointl_y[OBJLEN] = {0};int pointr_x[OBJLEN] = {0};int pointr_y[OBJLEN] = {0};//鼠标点击获取坐标信息void on_mouse( int event, int x, int y, int flags, void* ustc)  {      CvFont font;      cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);                if( event == CV_EVENT_LBUTTONDOWN )      {  if(lineflag){pointl_x[objnum] = x;pointl_y[objnum] = y;}else{pointr_x[objnum] = x;pointr_y[objnum] = y;objnum++;}        CvPoint pt = cvPoint(x,y);  #if 0        char temp[16];  if(lineflag)sprintf(temp,"L(%d,%d)",pt.x,pt.y);  //显示鼠标点击的左上角坐标elsesprintf(temp,"R(%d,%d)",pt.x,pt.y);  //显示鼠标点击的右上角坐标        cvPutText(curframe,temp, pt, &font, cvScalar(255, 255, 255));  #endif        cvCircle( curframe, pt, 2, cvScalar(255,0,0),CV_FILLED, CV_AA, 0 );  cvLine(curframe,cvPoint(pt.x,1),cvPoint(pt.x,IMGHEIGHT-1),Scalar(0,255,0),1);cvLine(curframe,cvPoint(1,pt.y),cvPoint(IMGWIDHT-1,pt.y),Scalar(0,255,0),1);        cvShowImage( "video", curframe );if(!lineflag)cvCopy(localframe,curframe,NULL);lineflag = !lineflag;    }   }  void main(int argc, char* argv[]){int frames = 0;int FrameNum = 0;//帧号int k = 0;int idx;int ROIx;int ROIy;int ROIwidth;int ROIheight;//CvCapture *capture = cvCreateFileCapture("test.avi");CvCapture *capture = cvCreateFileCapture(argv[1]);cout<<"视频读取成功!"<<endl;int rectflag = stoi(argv[2]);int startframe = stoi(argv[3]);int imgformat = stoi(argv[4]);frames = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);//获取视频帧数printf("total frames is %d\n", frames);cout<<"按键P可以控制视频的暂停/播放"<<endl;cout<<"暂停后用鼠标先后点击目标的左上角和有下角确定需要的保存区域"<<endl;uchar key = false;//用来设置暂停cvNamedWindow("video",0);//滑鼠事件呼叫函式cvSetMouseCallback( "video", on_mouse, 0 );while (capture){curframe = cvQueryFrame(capture); //抓取一帧FrameNum++;k++;if(FrameNum>startframe){cout<<"frame:"<<FrameNum-1<<endl;Mat img(curframe,0);//0是不复制影像,也就是iplImg的data共用同个记意位置,header各自有cvCopy(curframe,localframe,NULL);cvShowImage("video",curframe);//显示当前帧#if 0if(0 == FrameNum%3)//每隔一定帧数暂停一次用鼠标标定ROI区域{pause = true;}#endif//按键P切换暂停和播放key = cvWaitKey(1);if(key == 'p') pause = true;while(pause)if(cvWaitKey(0)=='p')pause = false;//暂停标定好区域后保存选定区域if(1){for(idx=0;idx<objnum;idx++){char resultImgName[256];ROIx = pointl_x[idx];ROIy = pointl_y[idx];if(rectflag>=1){ROIwidth = max(pointr_x[idx]-ROIx+1,pointr_y[idx]-ROIy+1);ROIheight = ROIwidth;}else{ROIwidth = pointr_x[idx]-ROIx+1;ROIheight = pointr_y[idx]-ROIy+1;}cvSetImageROI(localframe,cvRect(ROIx, ROIy, ROIwidth, ROIheight));//设置源图像ROIif(imgformat>0)sprintf(resultImgName, "obj/%d_%d.jpg", k,idx);elsesprintf(resultImgName, "obj/%d_%d.png", k,idx);cvSaveImage( resultImgName, localframe );cvResetImageROI(localframe);//源图像用完后,清空ROI}}objnum = 0;if(FrameNum == frames-2)//截止帧数break;}}cvWaitKey(0);cvDestroyWindow("video"); cvReleaseImage(&curframe);cvReleaseImage(&localframe);}



0 0
原创粉丝点击