我有一个指向CvContourTree的指针,我希望从中获得相关的轮廓。
我曾尝试使用会执行此操作的功能 -
cvContourFromContourTree(const CvContourTree * tree,CvMemStorage * storage,CvTermCriteria criteria)
但它给了我一个错误:
'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;
}
再次感谢您提供的任何帮助或建议。我向你们保证,非常感谢。
康纳
答案 0 :(得分:0)
嗯,你正在使用适当的方法。
CvContourTree* cvCreateContourTree(
const CvSeq* contour,
CvMemStorage* storage,
double threshold);
此方法将根据给定序列创建轮廓树,然后可用于比较两个轮廓。 要将轮廓树转换回序列,您将使用已发布的方法,但请记住初始化存储并创建TermCriteria(在您的示例中看起来没问题):
storage = cvCreateMemStorage(0);
CvSeq* cvContourFromContourTree(
const CvContourTree* tree,
CvMemStorage* storage,
CvTermCriteria criteria);
所以这个步骤应该适合您的转换,如果您的代码中没有任何遗漏,那么您应该发布更多内容,以便我们找到错误。