2011-07-01 140 views
8

我試圖從OpenCV庫運行createsamples示例。我可以一次加載一個圖像,它似乎工作正常。但是,當我嘗試加載一組圖像時,我得到一個解析錯誤。我不確定它是否在我的收集文件中是無效的,或者我在其他地方丟失了某些東西。以下是我的文本文檔的確切格式。OpenCV創建示例示例

文本文件的詳細內容:

Target1.JPG 1 0 0 1296 1152 
Target2.jpg 1 0 0 1890 709 

命令行調用:

-info "C:\Users\seb\Desktop\Learning Samples\Target\Target.txt" -num 10 -vec "C:\Users\seb\Desktop\Learning Samples\Target\Target.vec" -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20 

任何幫助是極大的讚賞。

+0

你可以通過整個命令行調用嗎? – red1ynx

+0

我編輯了問題以包含指定的命令行。 Aslo文本文件與圖像位於同一目錄中。 – Seb

回答

7

解析錯誤是因爲當你沒有指定你想生成POS圖像樣本的數量,createsamples將使用默認值是1000.但是,如果您的註釋文本文檔包含少於1000個對象的邊界框,則會出現分析錯誤。您仍然可以使用.vec文件進行級聯培訓。唯一的問題是號碼的信息不正確。有兩種方法可以解決它。

  1. 您手動計算文本文檔中的對象邊界框的數量。並指定小於或等於選項「-num」 的數字的值,例如createsamples -info xxxxx.txt -vec pos.vec -num [值]

  2. 您可以修改OPENCV_ROOT_DIR/modules/haartraining/createsamples.cpp。當未指定-num,則設定正的樣本數爲對象邊界框的文本文檔中的數

代碼片斷: 在createsamples.cpp INT NUM = 0;

在cvsamples.cpp

void icvWriteVecHeader(FILE* file, int count, int width, int height) 
{ 
    int vecsize; 
    short tmp; 

    fseek (file , 0 , SEEK_SET); 

    /* number of samples */ 
    fwrite(&count, sizeof(count), 1, file); 
    /* vector size */ 
    vecsize = width * height; 
    fwrite(&vecsize, sizeof(vecsize), 1, file); 
    /* min/max values */ 
    tmp = 0; 
    fwrite(&tmp, sizeof(tmp), 1, file); 
    fwrite(&tmp, sizeof(tmp), 1, file); 

    fseek (file , 0 , SEEK_END); 
} 

int cvCreateTrainingSamplesFromInfo(const char* infoname, const char* vecfilename, 
            int num, 
            int showsamples, 
            int winwidth, int winheight) 
{ 
    char fullname[PATH_MAX]; 
    char* filename; 

    FILE* info; 
    FILE* vec; 
    IplImage* src=0; 
    IplImage* sample; 
    int line; 
    int error; 
    int i; 
    int x, y, width, height; 
    int total; 

    assert(infoname != NULL); 
    assert(vecfilename != NULL); 

    total = 0; 
    if(!icvMkDir(vecfilename)) 
    { 

#if CV_VERBOSE 
     fprintf(stderr, "Unable to create directory hierarchy: %s\n", vecfilename); 
#endif /* CV_VERBOSE */ 

     return total; 
    } 

    info = fopen(infoname, "r"); 
    if(info == NULL) 
    { 

#if CV_VERBOSE 
     fprintf(stderr, "Unable to open file: %s\n", infoname); 
#endif /* CV_VERBOSE */ 

     return total; 
    } 

    vec = fopen(vecfilename, "wb"); 
    if(vec == NULL) 
    { 

#if CV_VERBOSE 
     fprintf(stderr, "Unable to open file: %s\n", vecfilename); 
#endif /* CV_VERBOSE */ 

     fclose(info); 

     return total; 
    } 

    sample = cvCreateImage(cvSize(winwidth, winheight), IPL_DEPTH_8U, 1); 

    icvWriteVecHeader(vec, num, sample->width, sample->height); 

    if(showsamples) 
    { 
     cvNamedWindow("Sample", CV_WINDOW_AUTOSIZE); 
    } 

    strcpy(fullname, infoname); 
    filename = strrchr(fullname, '\\'); 
    if(filename == NULL) 
    { 
     filename = strrchr(fullname, '/'); 
    } 
    if(filename == NULL) 
    { 
     filename = fullname; 
    } 
    else 
    { 
     filename++; 
    } 

    while (num<=0 || total<num) 
    { 
     int count; 

     error = (fscanf(info, "%s %d", filename, &count) != 2); 
     if(!error) 
     { 
      src = cvLoadImage(fullname, 0); 
      error = (src == NULL); 
      if(error) 
      { 

#if CV_VERBOSE 
       fprintf(stderr, "Unable to open image: %s\n", fullname); 
#endif /* CV_VERBOSE */ 
      } 
     } 
     else 
      if (num <= 0) break; 

     for(i = 0; i < count; i++, total++) 
     { 
      error = (fscanf(info, "%d %d %d %d", &x, &y, &width, &height) != 4); 
      if(error) break; 
      cvSetImageROI(src, cvRect(x, y, width, height)); 
      cvResize(src, sample, width >= sample->width && 
         height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR); 

      if(showsamples) 
      { 
       cvShowImage("Sample", sample); 
       if(cvWaitKey(0) == 27) 
       { 
        showsamples = 0; 
       } 
      } 
      icvWriteVecSample(vec, sample); 

         if (num > 0 && total >= num) break; 
     } 

     if (num<=0) 
      icvWriteVecHeader(vec, total, sample->width, sample->height); 

     if(src) 
     { 
      cvReleaseImage(&src); 
     } 

     if(error) 
     { 

#if CV_VERBOSE 
      fprintf(stderr, "%s(%d) : parse error", infoname, line); 
#endif /* CV_VERBOSE */ 

      break; 
     } 

     } 

    if(sample) 
    { 
     cvReleaseImage(&sample); 
    } 

    fclose(vec); 
    fclose(info); 

    return total; 
} 
+0

剛回來,並決定修改源文件。感謝您向我解釋這一點。 – Seb

+0

嗨Seb,你是如何得到createsamples.exe文件的?我正在使用opencv 2.2,但無法找到haar訓練所需的createSamples.exe或其他.exe文件 – MMH

+0

hi @Yiqun Hu,你知道使用haartraining和gentleboost分類器在600張圖像上訓練需要多長時間嗎?任何近似含糊的想法都將非常有幫助! – user961627

0

Target1.JPG - 它必須是createdamples.exe的相對路徑。不要Target.txt。

我已經在我的機器上測試,並得到這樣的結果:

d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release>opencv_createsamples.exe -info "d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release\Target.dat" -num 10 -vec "d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release\Target.vec" -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20 
Info file name: d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release\Target.dat 
Img file name: (NULL) 
Vec file name: d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release\Target.vec 
BG file name: (NULL) 
Num: 10 
BG color: 0 
BG threshold: 0 
Invert: FALSE 
Max intensity deviation: 100 
Max x angle: 0.6 
Max y angle: 0 
Max z angle: 0.3 
Show samples: FALSE 
Width: 20 
Height: 20 
Create training samples from images collection... 
d:\Programs\OpenCV-2.2.0\msvs-build\bin\Release\Target.dat(3) : parse errorDone. **Created 2 samples** 
+0

那麼需要更改文本信息文件或命令行參數?我問的原因是,當我在調試時,我可以看到它需要txt文件的位置並將其替換爲圖像文件的位置。如果我嘗試做完整的C目錄位置,那麼它將追加到全名,在這種情況下,我會得到「C:\ Users \ seb \ Desktop \ Learning_Samples \ Target \ C:\ Users \ seb \ Desktop \ Learning_Samples \ Target \ Target .JPG「 – Seb

+0

hi @ red1ynx,有點偏題,但約。使用haartraining和gentleboost訓練多久可以從opencv訓練600張圖像中的分類器?任何模糊的想法? – user961627

+0

對不起@ user961627,我很久沒有用opencv做過。 – red1ynx

0

其中一個原因可能是因爲信息的文件。

/家/我的/人臉檢測圖像/正片/ *的.jpg

確保所有的文件夾名稱不應該有空間,它的名字。就像上面顯示的「臉部探測器圖像」一樣,這應該是一些其他的名字,比如「圖像」或者沒有空間的任何東西。

將該文件夾重命名爲其原始路徑以及.info文件。

乾杯!

3

我努力讓opencv_createsamples在我的Windows機器上工作,它只是成功地工作。我想我會張貼細節來幫助別人。我正在使用opencv 2.4.8 on Windows 7

首先,我發現我需要在我的路徑變量中列出的目錄中使用opencv_createsamples.exe文件作爲OPENCV_DIR。我無法將exe文件複製到更方便的地方。

我在此目錄中爲我的圖像和我的文本文件設置了一個子目錄text_classifier。我在命令行上使用這個命令:

F:\Apps\opencv\build\x64\vc10\bin>opencv_createsamples.exe -vec text_classifier\text_binary_desc -info text_classifier\positive_examples.txt -num 146 -w 1350 -h 900 -bg text_classifier\negative_samples.txt

請注意,我必須列出圖像中選定區域的數量(-num 146)。我還列出了陽性樣本的寬度和高度。

裏面的文件positive_examples.txt,我需要有上市這樣的文件:

text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793

換句話說,這些文件必須相對於文件positive_examples.txt,而不是相對於上市exe文件(opencv_createsamples.exe)。當我試圖在文件相對上市exe文件,如:

text_classifier\text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793

then I got the error: Unable to open image: text_classifier\text_classifier\text_positives_clean\1839_Boettiger_001.JPG

然後我注意到,創建這個文件莫名其妙地錯過了加載一些文件到該目錄中,所以有在positive_examples列出的文件我的特別自動化系統.txt不在目錄中。如果exe文件找到positive_examples.txt中列出的不在目錄中的東西,那麼exe文件就會崩潰。我填補了圖像目錄中的空白。

後來我有一個奇怪的錯誤:無法打開圖片:129

我發現我犯了這個錯誤:

text_positives_clean\1862_Streckfuss_0006.JPG 1 813 502 382 353 129 46 526 798 682 780 117 67

你注意到這裏所說選定區域的數量爲1 (「JPG」後面的數字),而選定區域的數量真的是3?因此opencv_createsamples.exe在獲得單個選定區域後嘗試打開它作爲圖像找到的下一個東西,即'129'。它又摔倒了。

所以我將1更改爲3.然後我得到了一個解析錯誤,它實際上給了我一個在我的positive_examples.txt文件中的行號。我去的那行,發現我的條目中的一個沒有選擇的區域之間的空間,如:

949 315 157 67131 30 513 806

我解決了這個問題,增加了空間,最後的exe做了我所有的146個樣本。 Yoohoo!

希望這可以幫助別人。 :-)