cvCalcPGH 与 cvFindContours 的使用

Posted

技术标签:

【中文标题】cvCalcPGH 与 cvFindContours 的使用【英文标题】:cvCalcPGH usage with cvFindContours 【发布时间】:2012-08-05 05:49:06 【问题描述】:

由于某种原因,谷歌没有使用 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 我也在我的代码中检查。不确定如何解决。

【问题讨论】:

【参考方案1】:

谷歌不会给你很好的例子的原因是你所说的所有东西都被弃用了。

cvCalcPGH 在新的 opencv 中不再可用,您可能已经知道,因为您已包含旧库。

另外CV_CHAIN_CODE 是removed,你不能在新的opencv 中使用它。

你应该找时间把你的代码移植到新的 opencv 上,这个新的 opencv 正在流行并且会从其他人那里得到更多的帮助。

但是讨论您当前的代码,正如旧文档所说:

CV_CHAIN_CODE - 在 Freeman 链码中输出轮廓。所有其他 方法输出多边形(顶点序列)

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);

但同样,我不建议使用已弃用的方法和函数,您可能会找到更好的方法来做您想做的事情。

只是猜测您可能只想找到两个弗里曼代码之间的距离,您可能只是不计算 PGH,而只需使用一些其他距离函数,例如 here 讨论的那个。

【讨论】:

以上是关于cvCalcPGH 与 cvFindContours 的使用的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV cvFindContours - 如何分离轮廓的组件

用C++编写的图像处理函数,使用opencv2.3.1a,在Eclipse下编译,但cvFindContours函数报错

OpenCV函数cvFindContous提取图像轮廓

如何分离 Canny 检测到的边缘

openCV android 获取描绘物体轮廓的点坐标

OpenCV轮廓检测