问题描述:
在做目标跟踪程序时,经常需要读写某个文件夹下的图像文件。可以使用WIN32_FIND_DATA结构体配合FindFirstFile函数以及FindNextFile函数实现对特定文件夹下的文件遍历,但是有时候我们的图像序列命名是有规律的,如img_00001.jpg等,能不能通过组合文件夹名+前缀+编号+后缀的方式实现文件的读取呢,可以!
编写函数,实现功能:在txt配置文件中指定图像序列的文件夹路径、结果文件夹路径、图像前缀、图像数目、起始编号、目标个数、目标位置。代码如下
/****************************************************************************** 函数名:readConfig 功能:根据配置文件读取图像序列目录、图像前缀、图像扩展名、图像数目、开始编号,目标数目、目标位置。 参数: configFileName- 配置文件路径,后缀为.txt sourceDir - 图像序列文件夹名字 resultDir - 结果图像文件夹 imagePrefix - 前缀名 imageExt - 扩展名 imageNum - 图像数目 imageStartID - 序列开始编号 targetPos - 目标位置信息,存储目标上、下、左、右边界 targetNum - 目标数量 说明: ******************************************************************************/ bool readConfig(const char* configFileName, char* sourceDir, char* resultDir, char * imagePrefix, char *imageExt, int& imageNum, int& imageStartID, RECT* targetPos, int &targetNum ) { fstream f; char lineString[1000]; int readS=0; f.open(configFileName, fstream::in); if (f.bad()) { return false; } char param1[200]; strcpy(param1,""); char param2[200]; strcpy(param2,""); char param3[200]; strcpy(param3,""); /// 1.读取图像序列文件夹路径 // 注意:配置文件的第一行第三个参数才是文件夹路径。前两个参数是source_directory 和 "="号 f.getline(lineString, sizeof(lineString)); readS = sscanf (lineString, "%s %s %s", param1, param2, param3); // strcpy(sourceDir,param3); strcpy(param3,""); // 2.读取结果文件夹路径,注意:配置文件的第2行第三个参数才是结果文件夹路径 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %s", param1, param2, param3); strcpy(resultDir,param3); strcpy(param3,""); /// 3.读取图像前缀 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %s", param1, param2, param3); strcpy(imagePrefix,param3); strcpy(param3,""); /// 4.读取图像扩展名 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %s", param1, param2, param3); strcpy(imageExt,param3); strcpy(param3,""); /// 5.读取图像数目 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %d", param1, param2, &imageNum); /// 6.读取第一帧图像编号,比如1 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %d", param1, param2, &imageStartID); /// 7.读取第一帧图像中的目标数量 f.getline(lineString, sizeof(lineString)); readS=sscanf (lineString, "%s %s %d", param1, param2, &targetNum); /// 8.读取每个目标的位置,目标个数由上一步操作确定。 int x=0, y=0, w=0, h=0; for (int i=0; i<targetNum; i++) { f.getline( lineString, sizeof(lineString) ); readS=sscanf (lineString, "%s %s %d %d %d %d", param1,param2, &x, &y, &w, &h); targetPos[i].left = x; targetPos[i].right = x + w; targetPos[i].top = y; targetPos[i].bottom = y + h; } return true; }要求:配置文件格式应该如下:
source_directory = E:\data #注释:此行为源文件夹路径, result_directory = E:\data\result #注释:结果文件夹路径,在此文件夹下保存跟踪结果图像 imagePredix = #注释:此行imagePredix代表图像文件名字前缀 imageExtension = .jpg #注释:此行为图像文件扩展名,图像文件格式可以为.bmp或j.pg或.png imageNum = 64 #注释:此行为图像文件数量,假如在源文件夹路径source_directory下有100个图像,则imageNum值为100 startID = 1 #注释:图像文件起始编号 targetNum = 3 #注释:需要跟踪的目标数目,最少为1,最多为10 targetPosition_1 = 479 337 87 86 #注释:第1个目标在第一帧图像中的位置信息 targetPosition_2 = 958 332 85 87 #注释:第2个目标在第一帧图像中的位置信息 targetPosition_3 = 1262 320 98 90 #注释:第3个目标在第一帧图像中的位置信息最后,当需要在for循环中打开特定编号的文件时,使用如下命令,获取完整的文件路径:
sprintf(dstFileFullPath,"%s%s%d%s",fileDir,filePrefix,fileID,fileExt);其中dstFileFullPath为一个char 数组,将要包含特定编号的图像序列文件。
获得文件名后,在使用相关程序打开文件即可。
当然,如果你喜欢使用xml配合tinyxml或者rapidxml,那么,可以达到更好的效果。
说明:以上代码参考了compressive tracking的c++实现程序的相关代码,原程序在http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm,致谢!