我有一个指向CvContourTree的指针,我希望从中导出相关的轮廓。

我试图使用将执行此操作的功能-

cvContourFromContourTree(常量CvContourTree *树,CvMemStorage *存储,CvTermCriteria条件)

但这给了我一个错误:

'Matching_Hierarchial.exe中0x1005567f的未处理异常:0xC0000005:
访问冲突读取位置0x00000002。”

我定义了CvTermCriteria如下:

CvTermCriteria termcrit = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS,5,1);

有人可以提供一些示例代码,说明如何将轮廓转换为轮廓树,然后再次转换为轮廓。我将非常感谢您在此问题上的帮助。
谢谢,

康纳

感谢您的快速回复。请参阅附带的代码段。我从项目文件夹中获取了一个图像,并将其转换为二进制。然后,我找到了轮廓。使用任意轮廓,我通过多边形逼近简化了它的复杂性。我从该轮廓构造了一个轮廓树(我确信这是可行的,因为我已经使用cvMatchContourTrees()针对类似的轮廓树测试了该轮廓树,并获得了令人满意的结果)。但是,尽管阅读了所有关于函数和帖子的内容,但是我无法从轮廓树转换回轮廓结构。

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>
using namespace std;

#define CVX_RED CV_RGB(0xff,0x00,0x00)
#define CVX_BLUE CV_RGB(0x00,0x00,0xff)

int _tmain(int argc, _TCHAR* argv[])
{
    // define input image
    IplImage *img1 = cvLoadImage("SHAPE1.jpg",0);

    // define and construct binary image of input image
    IplImage *imgEdge1 = cvCreateImage(cvGetSize(img1),IPL_DEPTH_8U,1);
    cvThreshold(img1,imgEdge1,155,255,CV_THRESH_BINARY);

    // define and zero image to place polygon image
    IplImage *dst1 = cvCreateImage(cvGetSize(img1),IPL_DEPTH_8U,1);
    cvZero(dst1);

    // display ip and thresholded image
    cvNamedWindow("img1",1);
    cvNamedWindow("thresh1",1);
    cvShowImage("img1",img1);
    cvShowImage("thresh1",imgEdge1);

    // find all the contours of the image
    CvSeq* contours1 = NULL;
    CvMemStorage* storage1 = cvCreateMemStorage();
    int numContour1 = cvFindContours(imgEdge1,storage1,&contours1,sizeof(CvContour),CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);
    cout<<"number of contours"<<numContour1<<endl;

    // extract a contour of interest
    CvSeq* poly_approx1 = contours1->v_next; // interested in vertical level becaue tree structure

    // CALCULATE PERIMETER
    double perimeter1 = cvArcLength((CvSeq*)poly_approx1,CV_WHOLE_SEQ,-1);

    // CREATE POLYGON APPROXIMATION -
    // NB: CANNOT USE 'CV_CHAIN_CODE'ARGUEMENT IN THE cvFindContours() call
    CvSeq* polySeq1 = cvApproxPoly((CvSeq*)poly_approx1,sizeof(CvContour),storage1,CV_POLY_APPROX_DP,perimeter1*0.02,0);

    // draw approximated polygon
    cvDrawContours(dst1,polySeq1,cvScalar(255),cvScalar(255),0,3,8);    // draw

    // display polygon
    cvNamedWindow("Poly Approx1",1);
    cvShowImage("Poly Approx1",dst1);

// NOW WE HAVE A POLYGON APPROXIMATED CONTOUR

    // CREATE A CONTOUR TREE
    CvMemStorage *treeStorage1 = cvCreateMemStorage(0);
    CvContourTree* tree1 = cvCreateContourTree((const CvSeq*)polySeq1,treeStorage1,0);

// TO RECONSTRUCT A CONTOUR FROM THE CONTOUR TREE
// CANNOT GET TO WORK YET...
    CvMemStorage *stor = cvCreateMemStorage(0);
    CvTermCriteria termcrit = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS ,5,1); // more later
    /* the next line will not compile */
    CvSeq *contour_recap = cvContourFromContourTree(tree1,treeStorage1,termcrit);


    cvWaitKey(0);
    return 0;
}

再次感谢您可能提供的任何帮助或建议。我向您保证,我们将不胜感激。

康纳

最佳答案

好吧,您正在使用适当的方法。

CvContourTree* cvCreateContourTree(
const CvSeq* contour,
CvMemStorage* storage,
double threshold);

该方法将根据给定的序列创建轮廓树,然后可将其用于比较两个轮廓。
要将轮廓树转换回序列,您将使用已经发布的方法,但是请记住初始化存储并创建TermCriteria(在示例中看起来不错):
storage = cvCreateMemStorage(0);
CvSeq* cvContourFromContourTree(
const CvContourTree* tree,
CvMemStorage* storage,
CvTermCriteria criteria);

因此,此步骤对于您的转换应该可以,并且如果您的代码中没有缺少任何内容,那么您应该发布更多代码,以便我们发现错误。

关于opencv - OpenCV:从轮廓树转换为轮廓-cvContourFromContourTree(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7300455/

10-14 15:53