4

何らかの理由で、グーグルにはcvCalcPGH()を使用する良い例も、輪郭のマッチングにFreemanコードを使用する他の良い例もありません。だから私はそれを作ろうとします:

#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であり、assert()はCV_SEQ_ELTYPE( contour ) != CV_32SC2、コードでもチェックするためのものです。それを修正する方法がわからない。

4

1 に答える 1

6

グーグルがあなたに良い例を与えない理由は、あなたが話しているすべてのものが非推奨になっているからです。

cvCalcPGHレガシーライブラリが含まれているため、すでに知っている可能性のある新しいopencvでは使用できなくなりました。

また、CV_CHAIN_CODE削除され、新しい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);
}

しかし、繰り返しになりますが、非推奨のメソッドや関数で作業することはお勧めしません。あなたが望むことを行うためのより良い方法を見つけるかもしれません。

2つのフリーマンコード間の距離を見つけたいと思うだけで、PGHの計算を避けて、ここで説明するような他の距離関数を使用することができます。

于 2012-08-13T00:46:16.907 に答える