2011-09-04 193 views
2

我有一个指向CvContourTree的指针,我希望从中得出相关的轮廓。OpenCV:从轮廓树转换为轮廓 - cvContourFromContourTree()

我曾尝试使用,将做到这一点的功能 -

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

再次感谢您的任何帮助或建议,您可能会给。我向你保证非常感谢。

conor

回答

0

那么,你正在使用适当的方法。

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

该方法从一个给定序列中,然后可将其用于比较两个轮廓创建轮廓树。 要轮廓树转换回一个序列,你将使用已发布的方法,但记得要初始化存储和创建TermCriteria(在你的例子看起来不错):

storage = cvCreateMemStorage(0); 
CvSeq* cvContourFromContourTree(
const CvContourTree* tree, 
CvMemStorage* storage, 
CvTermCriteria criteria); 

所以这个步骤应该是确定对于你的转换,如果你的代码没有什么缺失,你应该发布更多的代码,这样我们才能发现错误。