Мне нужно протестировать свой детектор, написанный самим собой, с использованием Hog Descriptor (документ Dalal) в наборе данных Scientific (набор данных INRIA). У меня в папке есть тысячи изображений с положительными и отрицательными значениями для обучения машине опорных векторов (SVM). Однако, чтобы пометить Изображения как положительные (1.0) или отрицательные (-1.0), мне нужно прочитать информацию из текстового файла, который поставляется с набором данных в так называемом формате «PASCAL Annotation».
Моя проблема в том, что я не знаю, как эффективно читать этот формат. Я использую C ++ и OpenCV. Кто-нибудь знает, как это сделать эффективно? Уже есть фрагменты кода для C ++?
В конце мне нужен цикл, который проходит через файл «Annotations.lst», где перечислены все имена файлов изображений. Программа загружает изображение и соответствующий файл аннотации (picturename.txt), чтобы увидеть, относится ли это изображение к положительным или отрицательным обучающим данным (или позже при фактическом обнаружении: принадлежит ли проверенное изображение обнаруженному человеку или нет)
Спасибо за вашу помощь!
Может быть, это не самая лучшая реализация, но работает отлично, надеюсь, она станет полезной даже сегодня! Вам понадобится библиотека файловой системы для работы с файлами.
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
}
Других решений пока нет …