前几天我在 这里 分析了一下代码
但只是简单做了个记录,没有说明具体的使用
图像跟踪,需要三样东西: 跟踪程序,跟踪图片序列,初始框
对应的是:KCFTracker代码,图像数据和名为images.txt的图像序列名字,初始框region.txt
KCFTracker代码,已经分析过了
图像数据,不同人写的代码接口通常不同,但主要是图片和视频的来回转换,而且对于结果来说,通常转换成视频比较易于观看
在这分析2个程序,图片序列转换成视频文件,和视频文件转换成图像序列
1)视频拆成图片帧:
使用OpenCV读取视频文件,自己定义输出图像序列的名字和存储位置。给出输入文件和起始、停止保存的帧号,保存中间的帧
argv[1]是视频文件名字
argv[2]是视频文件从开始保存的帧号:使用时间*帧频计算
argv[3]是视频文件从停止保存的帧号:使用时间*帧频计算
argv[4]是保存图片帧时,每argv[4]帧,保存一帧
在Ubuntu上面运行的时候,通常是如下命令:
./Opencv_player_save /media/li/OS/Users/lmw/Desktop/\[SHANA\]1481948372.mp4 5825 7100 1
即保存.mp4文件从5825到7100中间的每一帧。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char ** argv){
int startframe = 8881; //图片开始帧号
int endframe = 164;
char cur_fn[255];
char prefix[] = "/media/li/OS/Users/lmw/Desktop/1/";//图片序列的路径
char ext[] = ".jpg"; //序列图片的后缀名
//open the video
cv::VideoCapture capture(argv[1]);
//check the video
if(!capture.isOpened())
return 1;
//get the rate
double rate = capture.get(CV_CAP_PROP_FPS);
bool stop(false);
cv::Mat frame;
cv::namedWindow("Opencv Player");
capture.read(frame);
std::cout<<"the width is "<<frame.cols<<std::endl;
std::cout<<"the highth is "<<frame.rows<<std::endl;
//get the delay
int delay = 1000/rate;
if (delay == 0)
delay = 33;
int god = 0;
//show every picture of the video
while(!stop){
//try to get next picture
if(!capture.read(frame))
break;
//cv::imshow("Opencv Player", frame);
//if(cv::waitKey(delay)>=0)
// stop = true;
god++;
cout<<"frame :" <<god<<endl;
if(god>atof(argv[2]) && god<atof(argv[3]) && god%((int)atof(argv[4]))==0){
strcpy(cur_fn,"");
sprintf(cur_fn,"%s%04d%s",prefix,startframe,ext);
startframe++;
cv::imwrite(cur_fn, frame);
}
else if(god>=atof(argv[3])){
exit(0);
}
}
capture.release();
}
2)图片帧整合成视频:
在这里需要定义一副图像的宽、高,视频帧频,输出文件名字,图片文件的路径和起始结束的序号:
#include <opencv/cv.h>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
/*******************************************************/
int main()
{
int i = 0;
//初始化视频编写器,参数根据实际视频文件修改
CvVideoWriter* writer = 0;
int isColor = 1;
//int fps = 25; // or 30
double fps = 15;
int frameW = 1920;
int frameH = 1080;
writer = cvCreateVideoWriter("RGB.avi",CV_FOURCC('X','V','I','D'),fps, cvSize(frameW, frameH), isColor);
printf("\tvideo height:%d\n\tvidoe width:%d\n\t\fps:%f\n",frameH, frameW, fps);
int startframe = 1; //图片开始帧号
int endframe = 1654;
char cur_fn[255];
char prefix[] = "/home/li/work/KCF/project/KCF_src/";//图片序列的路径
char ext[] = ".jpg"; //序列图片的后缀名
//存储视频文件
IplImage* img = 0;
// int nFrames = 50;
// for (i = 0; i < nFrames; i++)
// {
// cvWriteFrame(writer,img); //写入一帧到一个视频文件中 cvGrabFrame(capture);
// }
while (startframe <= endframe)
{
strcpy(cur_fn,"");
sprintf(cur_fn,"%s%04d%s",prefix,startframe,ext);
img = cvLoadImage(cur_fn,isColor);
if (!img){
printf("can not open file\n");
return 0;
}
//cvNamedWindow("mainWin0",CV_WINDOW_AUTOSIZE);
//cvShowImage("mainWin0",img);
//cvWaitKey(20);
cvWriteFrame(writer,img);
cvWaitKey(20);
startframe++;
cvReleaseImage(&img);
}
//创建窗口
//cvNamedWindow("mainWin",CV_WINDOW_AUTOSIZE);
//cvShowImage("mainWin",img);
//cvWaitKey(20);
//释放视频存储器
cvReleaseVideoWriter(&writer);
}
3)images.txt图像序列生成
在这还要生成名为images.txt的图像序列文件
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
string result_name = "images1.txt";
ofstream result("images1.txt");
if (!result)
cout<<"error!"<<endl;
int img_num = 8951;
for (int i=8881;i<=img_num;i++)
{
char img_name[80];
result<<"/media/li/OS/Users/lmw/Desktop/1/";
sprintf(img_name, "%04d.jpg\n",i);
result<<img_name;
}
return 0;
}
4)编辑区域文件region.txt,应该是左上角点,右上角点,左下角点,右下角点的顺序
直接读取目标位置,修改坐标即可