2012-08-08 36 views
4

由於某些原因,谷歌沒有使用cvCalcPGH()的好例子,也沒有使用Freeman代碼進行輪廓匹配的其他好例子。所以,我儘量做到:cvCalcPGH用法與cvFindContours

#include "opencv2/opencv.hpp" 
#include "opencv2/legacy/legacy.hpp" 

int 
main(int argc, char* argv[]) { 

     IplImage* g_gray = cvLoadImage("lisa.png",CV_LOAD_IMAGE_GRAYSCALE); 
     cvThreshold(g_gray, g_gray, 100, 255, CV_THRESH_BINARY); 

     CvMemStorage* storage=cvCreateMemStorage(0); 
     CvSeq* firstContour=NULL; 

     int a=cvFindContours(g_gray, storage, &firstContour,sizeof(CvChain),CV_RETR_LIST, CV_CHAIN_CODE); 

     CvHistogram *hist; 
     int h_bins = 30, s_bins = 30; 
     float h_ranges[] = { 0, 180 }; 
     float s_ranges[] = { 0, 255 }; 
     int hist_size[] = { h_bins, s_bins }; 
     float* ranges[] = { h_ranges, s_ranges }; 

     hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1); 
     if(CV_SEQ_ELTYPE(firstContour) != CV_32SC2) { 
       printf(":(\n"); 
     } 

     cvCalcPGH((CvSeq *)firstContour,hist); 
     return 0; 

} 

cvFindContours()將運行證明,但cvCalcPGH()將失敗:

$ ./calcpgh 
:(
OpenCV Error: Unsupported format or combination of formats (The contour is not valid or the point type is not supported) in cvCalcPGH, file /Users/tonu-samuel/OpenCV-2.4.2/modules/legacy/src/pgh.cpp, line 351 
terminate called throwing an exceptionAbort trap: 6 
$ 

OpenCV的是2.4.2,並表示斷言()是CV_SEQ_ELTYPE(contour) != CV_32SC2我檢查也在我的代碼中。如何解決它不確定。

回答

6

谷歌不會給你很好的例子的原因是,你談論的所有事情都被棄用了。

cvCalcPGH不再在新的opencv中可用,您可能已經知道,因爲您已經包含舊版庫。

另外CV_CHAIN_CODEremoved,你不能在新的opencv中使用它。

你應該找到時間把你的代碼移植到正在趨勢化的新opencv中,並且會從別人那裏獲得更多的幫助。

但在討論當前的代碼,如舊文件說:

CV_CHAIN_CODE - 在弗里曼鏈碼的輸出輪廓。所有其他 方法輸出的多邊形(的頂點的序列)

cvFindContours輸出始終頂點的序列和CV_CHAIN_CODE僅僅是一個例外。這就是爲什麼cvCalcPGH無法理解這些代碼。

而且您可能已經使用其他近似方法測試了代碼,您應該已經看到cvCalcPGH可以很好地處理多邊形。

您應該將Freeman代碼自己轉換爲多邊形,然後您可以使用任何您想要的opencv方法。但沒有這個,我還沒有看到一種可以解釋Freeman代碼本身的方法。

我不知道究竟是如何這種轉換應該做的,但使用下面的代碼,這是無恥地從Sara Maher Mohammad被盜,您可以提取這些代碼,並開始自己的解釋是:

CvChainPtReader reader; 

cvStartReadChainPoints((CvChain*) firstContour, &reader); 
for (int i = 0; i < firstContour->total; i++) { 
    CV_READ_SEQ_ELEM(reader.code, (*((CvSeqReader*)&(reader)))); 
    printf("%d \n", reader.code); 
} 

但同樣,我不建議您使用已棄用的方法和功能,您可能會找到更好的方法來執行您想要的操作。

只是猜測你可能只是想找到兩個Freeman碼之間的距離,你可能不想計算PGH,只是使用一些其他的距離函數,如here