前幾天我在 這裡 分析了一下代碼
但只是簡單做了個記錄,沒有說明具體的使用
映像跟蹤,需要三樣東西: 跟蹤程式,跟蹤圖片序列,初始框
對應的是: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 30double 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,應該是左上方點,右上方點,左下角點,右下角點的順序
直接讀取目標位置,修改座標即可