2

我需要在科学数据集(INRIA 人数据集)上使用 Hog Descriptor(Dalal 论文)测试我自己编写的人检测器。我的文件夹中有数千个 pos 和 neg 图像来训练支持向量机 (SVM)。但是,要将图像标记为正 (1.0) 或负 (-1.0),我需要从数据集随附的文本文件中读取信息,该文件采用所谓的“PASCAL 注释”格式。

我的问题是我不知道如何有效地阅读这种格式。我正在使用 C++ 和 OpenCV。有谁知道如何有效地做到这一点?是否已经有 C++ 的代码片段?

最后,我需要一个循环来遍历文件“Annotations.lst”,其中列出了所有图片文件名。程序加载图片和对应的标注文件(picturename.txt),看这张图片是属于正面还是负面的训练数据(或者稍后实际检测时:测试的图片是否属于被检测的人)

谢谢你的帮助!

4

1 回答 1

0

也许这不是最好的实现,但工作正常,希望它即使在今天也有用!您将需要文件系统库才能处理文件。

string line,value; //Line stores lines of the file and value stores characters of the line
int i=0; //Iterate through lines
int j=0; //Iterate through characters
int n=0; //Iterate through ,()-...
char v; //Stores variable value as a char to be able to make comparisions easily

vector <Rect> anotations; //Stores rectangles for each image
vector <int> bbValues; //Bounding box values (xmin,ymin,xmax,ymax)

fs::path anotationsFolder = "THE FOLDER PATH OF ANOTATIONS"; //Path of anotations folder
fs::path anotationsParsedFolder = "THE FOLDER PATH TO STORE PARSED ANOTATIONS"; //Path to store new anotations

fs::recursive_directory_iterator it(anotationsFolder); //Iteradores of files
fs::recursive_directory_iterator endit;

cout<<"Loading anotations from "<<anotationsFolder<<endl;

while((it != endit)) //Until end of folder
{
    if((fs::is_regular_file(*it))) //Good practice
    {
        fs::path imagePath(it->path()); //Complete path of the image

        cout<<"Reading anotations from"<<it->path().filename()<<endl;

        ifstream inputFile; //Declare input file with image path
        inputFile.open(imagePath.string().data(), std::ios_base::in);

        i=0;
        while (! inputFile.eof() ){ //Until end of file

            getline (inputFile,line);//Get lines one by one

            if ((i>=17) && ((i-17)%7==0)){ //In lines numer 17,24,31,38...where bounding boxes coordinates are

                j=69;
                v=line[j]; //Start from character num 69 corresponding to first value of Xmin

                while (j<line.size()){ //Until end of line

                    if (v=='(' || v==',' || v==')' || v==' ' || v=='-'){ //if true, push back acumulated value unless previous value wasn't a symbol also
                        if (n==0){
                            bbValues.push_back(stoi(value)); //stoi converts string in to integer ("567"->567) 
                            value.clear();
                        }
                        n++;
                    }
                    else{
                        value+=v; //Append new number
                        n=0;//Reset in order to know that a number has been read
                    }
                    j++;
                    v=line[j];//Read next character
                }
                Rect rect(bbValues[0],bbValues[1],bbValues[2]-bbValues[0],bbValues[3]-bbValues[1]); //Build a rectangle rect(xmin,ymin,xmax-xmin,ymax-ymin)
                anotations.push_back(rect);
                bbValues.clear();
            }
            i++;//Next line
        }
        inputFile.close();            

        cout<<"Writing..."<<endl;

        //Save the anotations to a file
        ofstream outputFile; //Declare file
        fs::path outputPath(anotationsParsedFolder / it->path().filename());// Complete path of the file
        outputFile.open(outputPath.string().data(), ios_base::trunc);

        // Store anotations as x y width heigth
        for (int i=0; i<anotations.size(); i++){
            outputFile<<anotations[i].x<<" ";
            outputFile<<anotations[i].y<<" ";
            outputFile<<anotations[i].width<<" ";
            outputFile<<anotations[i].height<<endl;
        }
        anotations.clear();
        outputFile.close();
    }
    ++it;//Next file in anotations folder
}
于 2016-04-07T00:05:45.737 回答