2011-11-17 5 views
1

질문 답변 됨, 질문 끝 부분의 해결책을 참조하십시오. 더 많은 의견/답변을 환영합니다.OpenCV 프로젝트의 C/C++에서 CvSeq 또는 다른 유형의 동적 메모리 저장 공간에 추가

그래서 내가 하나 개의 메모리 저장소에 내 모든 요소를 ​​받고 몇 가지 문제가 있어요, 내가 관리해야 가장 좋은 가게마다 덮어 쓰기 만 슬프게도 충분하지 않은 덮어 쓰기 마지막 요소를 얻을 수있다 .

나는 주로 Java 프로그래머이므로 C 언어 대신 Java 용어를 사용하고 C 객체를 참조 할 때 잘못된 유형을 언급 할 수 있으므로 사전에 appoligise 할 수 있습니다. 나 포인터에 시작).

궁극적으로 내가하려는 것은 이미지의 모든 볼록한 결함을 잡고 하나의 연속 된 공간에 저장 한 다음 JNI를 통해 Java로 다시 전달하는 것입니다. 저장소의 유형은 중요하지 않습니다.이 단계에서는 작업이 필요하며 작업을 수행 할 수 있습니다. 스택, 대기열, 목록, 벡터 또는 유사한 작업을 수행 할 것이라고 생각합니다. 현재 내가 하나의 큰 CvSeq에 루프 CvSeq 객체의 라운드 추가 그룹을하려고했는데, 내 코드를 게시하고 게시 후 논의 할 것이다 :

CvSeq *allDefects; 
allDefects = cvCreateSeq(0, sizeof (CvSeq), sizeof (CvConvexityDefect), mem_storage4); 

CvContourScanner scanner3 = cvStartFindContours(img_bin, mem_storage3); 
while ((c2 = cvFindNextContour(scanner3)) != NULL) { 
    if (threshold != 0 && cvContourPerimeter(c2) < threshold) { 
     cvSubstituteContour(scanner3, NULL); 
    } else { // otherwise create the hull 
     CvSeq* c_new; 
     c_new = cvConvexHull2(c2, mem_storage5, CV_CLOCKWISE, 0); 
     CvMemStorage* storage; 
     storage = cvCreateMemStorage(0); 
     defects = cvConvexityDefects(c2, c_new, storage); 
     allDefects = defects; 
     //   for (int i = 0; i < defects->total; i++){ 
     //   cvSeqPush(allDefects, CV_GET_SEQ_ELEM(CvSeq, defects, i)); 
     //   } 
    } 
} 

그래서 우리는 스캐너를 작성하는 동안 우리는 찾을 수 있습니다 우리가하는 등고선은 주어진 문턱 값보다 큽니다. 우리는 그것을 선체로 만들고 그것과 선체 사이의 결함을 발견한다고 가정합니다. 이 결함 내가 allDefects 때마다 우리는 루프 라운드 그러나 내가가는 얻을 수있는 유일한 방법은 allDefects에게이 각을 덮어 쓰기하는 의미 동일 에 결함을 만드는 것입니다 추가 할 것이 멀티 개체가 수 있음을 의미 고리. 당신은 내가 스택처럼 집어 넣으려고 시도 주석 코드를 조금 볼 수 있지만이 오류와 충돌 :

Assertion failed: sizeof(((defects))->first[0]) == sizeof(CvSeqBlock) && ((defects))->elem_size == sizeof(CvSeq), file vtoolsModified.cpp, line 1407

그래서 documention으로는 "cvConvexityDefects()으로 돌아 간다 CvConvexityDefect 구조의 순서를"간다 즉 CvSeq으로 가득합니다. CvConvexityDefect (s)입니다. 어떤 도움이다 경우 cvConvexityDefects의 signiture는 다음과 같습니다 그래서

CVAPI(CvSeq*) cvConvexityDefects(const CvArr* contour, const CvArr* 
    convexhull, CvMemStorage* storage CV_DEFAULT(NULL)); 

가이 모든 결함을 추가 그들 사이의 결함을 발견, 선체를 찾아 윤곽을 찾을 내가 뭘 찾고 있어요 것은 요약 하나의 대형 상점, 윤곽이 남아 있지 않을 때까지 반복, 모든 결함이있는 대형 상점을 Java로 반환하십시오. 그것은 대담한 것입니다. 나는 도움을 찾고 있습니다.

누구든지 내가 할 수있는 출처의 방향으로 나를 도울 수 있습니까? (나는이 특정 문제에 대해 2 주 동안 노력해 왔으므로 많은 리소스를 쏟아 붓았으며, 실제로는 단순한 루프가 무엇이되어야 하는지를 정확히 파악하지 못해서 정말 실망 스럽다.)

감사합니다.

EDIT - 의견이 더 많은 결과가 추가되었습니다.

편집 2 - C의 이해 나의 부족이 근본적인 문제처럼

가 보이는 아래 답변 질문, 그 결과는, 고정 된 코드입니다.나는 내가 CvConvexityDefect를 사용해야했던 장소에서 CvSeq을 사용해야한다고 가정하고있었습니다. 다음과 같이 수정 된 코드는 다음과 같습니다

CvSeq *defects; 
CvSeq *allDefects; 
allDefects = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvConvexityDefect), mem_storage4); 

CvContourScanner scanner3 = cvStartFindContours(img_bin, mem_storage3); 
while ((c2 = cvFindNextContour(scanner3)) != NULL) { 
    if (threshold != 0 && cvContourPerimeter(c2) < threshold) { 
     cvSubstituteContour(scanner3, NULL); 
    } else { // otherwise create the hull 
     CvSeq* c_new; 
     c_new = cvConvexHull2(c2, mem_storage5, CV_CLOCKWISE, 0); 
     CvMemStorage* storage; 
     storage = cvCreateMemStorage(0); 
     defects = cvConvexityDefects(c2, c_new, storage); 
     //   allDefects = defects; 
     if (defects->total < 100) { 
     for (int i = 0; i < defects->total; i++) { 
      CvConvexityDefect* element = CV_GET_SEQ_ELEM(CvConvexityDefect, defects, i); 
      if (element != 0){  
       cvSeqPush(allDefects, element);     } 
      } 
     } 
    } 
} 

당신은 내가 또한 확실히 100 미만 결함이 반환하게 확인하고 볼 수 있으며, 제작 (때로는 시스템을 나누기 수백만이다) 널 (null)을 반환하지 않습니다 CV_GET_SEQ_ELEM 확인 이 null을 반환 할 수 있지만 난 그냥 경우에 확인해 보겠습니다 경우 (잘 모르겠어요

답변

1

내 생각 엔 당신의 루프가이 라인에서 실수가 있다는 것입니다.

CV_GET_SEQ_ELEM(CvSeq, defects, i) 

당신이 보는 경우를 정의 그것은 :

#define CV_GET_SEQ_ELEM(elem_type, seq, index) CV_SEQ_ELEM((seq), elem_type, (index)) 
첫 번째 매개 변수와 순서가 아닌 유형 (CvSeq)을 저장할 수

다른 방법 (cvFindContours 보통 CvPoint의 시퀀스를 만드는) 요소의 형태로 가지고 있음을 알 수

당신의 순서는 각각의 객체에 대해 분리 된 결함을 유지, 목록의 배열을

void* cvCvtSeqToArray(const CvSeq* seq, 
          void* elements, 
          CvSlice slice = CV_WHOLE_SEQ 
         ); 

를 사용하고 저장하는 것입니다. 필요한 항목에 따라 더 많은 옵션이 있습니다.

EDIT2 :

이 좋아, 그래서 난 그냥 cvConvexityDefects을 검토하고 구조의 시퀀스를 반환하는 것을보고하지 CvPoint, 다음 allDefects는 사용자 정의 만든 CvSeq해야 당신은 당신이 다음과 같이 코드를 수정합니다 :

cvSeqPush(allDefects, CV_GET_SEQ_ELEM(CvConvexityDefect, defects, i)); 
+0

입력 해 주셔서 감사합니다 그러나 이것은 내 문제를 해결하지 않습니다. 나는 방금 질문을 다시 읽었으며 조금 애매하다. 그 동안 내가 찾고있는 배열/목록/벡터는 cvConvexityDefects의 데이터로 채워져 있습니다. 나는 cvConvexityDefects에서 반환되는 것이므로 CvSeq이 유형이라고 생각했지만 cvConvexityDefects가 cvConvexityDefect 유형의 CvSeq를 반환한다는 것을 의미한다고 생각합니다. (유형과 기능 사이에 누락 된 점에주의하십시오.) – RyanfaeScotland

+0

Ok, 내 대답에 대한 두 번째 편집이있었습니다. :) – Adrian

+0

그래, 그게 분류있어. 관심있는 사람들을 위해 조정 된 코드를 질문 맨 아래에 편집합니다. 도움을 주셔서 감사합니다 @ 애드리안 – RyanfaeScotland