Presentation is loading. Please wait.

Presentation is loading. Please wait.

8장 Contours 2013. 09. 30 장 호욱.

Similar presentations


Presentation on theme: "8장 Contours 2013. 09. 30 장 호욱."— Presentation transcript:

1 8장 Contours 장 호욱

2 개요 영상은 일반적으로 객체 표현을 포함 영상 분석의 목표 중 하나는 이런 객체를 식별하고 추출하는 것임
객체 감지/인식 애플리케이션에서 첫 번째 단계는 관심 객체가 위치했음을 보여주는 영상을 만드는것임 Edge detector를 사용하여 이미지의 edge pixels을 찾을 수 있으나 이 edge들이 객체 자체로써 어떤 정보를 제공하진 않음 edge pixel을 찾은 후 해야 할 일은 이 픽셀들을contours로 모으는 작업임

3 목차 메모리 스토리지 시퀀스 외곽선 검출 외곽선 매칭

4 Memory Storage OpenCV는 동적객체 생성시 memory storage 사용 linked list 구조
CvMemStorage* cvCreateMemStorage( int block_size =0); //생성, 기본 블록 크기 64KB void cvReleaseMemStorage(CvMemStorage** storage) // 저장공간 해제 void cvClearMemStorage(CvMemStorage* storage) // 재사용 void* cvMemStorageAlloc(CvMemStorage* storage, size_t size) // 메모리 버퍼 할당

5 Sequence 메모리 스토리지 내에 저장되는 객체들 중 하나 다른 구조체들의 linked list
다양한 객체로 구성된 시퀀스를 생성 할 수 있게 함 typedef struct CvSeq {      int         flags;          // 3가지 종류, 객체타입, 타입, 특징     int         header_size;        CvSeq*      h_prev;              CvSeq*      h_next;              CvSeq*      v_prev;              CvSeq*      v_next;            int         total;              int         elem_size;          schar*      block_max;          schar*      ptr;                int         delta_elems;          CvMemStorage*      storage;            CvSeqBlock*        free_blocks;       CvSeqBlock*        first;          } CvSeq;

6 Sequence 시퀀스 생성 CvSeq* cvCreateSeq( int seq_flags, //시퀀스의 종류
        size_t header_size,  //시퀀스 헤더의 크기         size_t elem_size,    //시퀀스가 포함할 객체의 크기         CvMemStorage* storage  //시퀀스가 메모리를 할당할 메모리 스토리지 ); 시퀀스 삭제 void cvClearSeq(CvSeq* seq); //할당된 블록 반환 안함 //동일한 시퀀스에서만 재사용 시퀀스 원소 접근 schar* cvGetSeqElem(const CvSeq* seq, int index); //임의의 원소 접근 int cvSeqElemIdx(const CvSeq* seq, const void* element, CvSeqBlock** block=NULL); // 특정 원소의 위치 파악

7 Sequence 시퀀스 복사 cvCloneSeq(const CvSeq* seq, CvMemstorage* storage = NULL ) CvSeq* cvSeqSlice( //시퀀스에서 일부 추출 Const CvSeq* seq, CvSlice slice, CvMemStorage* storage = NULL, Int copy_data=0 ) 원소 삽입과 삭제 void cvSeqInsertSlice(CvSeq* seq, int before_index, const CvArr* from_arr); void cvSeqRemoveSlice(CvSeq* seq, CvSlice slice);

8 Sequence 시퀀스 비교 typedef int (*CvCmpFunc)(const void* a, const* b, void* userdata); // a와b는 정렬되고 있는type의 elements에 대한 포인터 // userdata 는 어떤 추가 데이터 구조에 대한 포인터 임. // a가 b보다 크면 -1을 반환하고 반대면 +1, 같으면 0을 반환 시퀀스내 원소 순서를 반대로 void cvSeqInvert( CvSeq* seq ); 시퀀스 분할 cvSeqPartition

9 Sequence char* cvSeqPush() char* cvSeqPushFront() char* cvSeqPop()
시퀀스를 스택처럼 사용 가능 = char* cvSeqPush() char* cvSeqPushFront() char* cvSeqPop() char* cvSeqPopFront() char* cvSeqPushMulti() char* cvSeqPopMulti() 원소 삽입, 삭제 char* cvSeqInsert() char* cvSeqRemove()

10 Sequence 시퀀스 reader, writer
시퀀스를 이용한 작업에서 최상의 성능을 얻기 위해서 시퀀스에 값을 저장하기 위한 CvSeqWriter 구조체와 시퀀스의 값을 읽어오기 위한 CvSeqReader 구조체 사용 void cvStartWriteSeq(         int seq_flags,         int header_size,         int elem_size,         CvMemStorage* storage,         CvSeqWriter* writer  );  CvSeq* cvEndWriteSeq(CvSeqWriter* writer);  void cvStartAppendToSeq(CvSeq* seq, CvSeqWriter* writer);  void cvFlushSeqWriter(CvSeqWriter* writer);  CV_WRITE_SEQ_ELEM(elem, writer)  CV_WRITE_SEQ_ELEM_VAR(elem_ptr, writer)

11 외곽선 검출 외곽선이란 영상 내 곡선을 나타내는 점들의 리스트로 정의
Contour : 이미지 안에 어떤 곡선을 표현하는 점들의 목록 OpenCV에선 Contour를 sequence로 표현 함. cvFindContours()는 이진 이미지로부터 Contour를 계산 함. cvCanny()나 cvThreshold() 혹은 cvAdaptiveThreshold()에 의해 생성된 이미지를 사용 할 수 있음.

12 외곽선 검출 int cvFindContours( CvArr* image, CvMemStorage* storage,
      CvSeq** first_contour,       int header_size=sizeof(CvContour),       int mode=CV_RETR_LIST,       int method=CV_CHAIN_APPROX_SIMPLE,       CvPoint offset=cvPoint(0,0) ); img : 8비트 단일 채널의 입력 영상, 이진영상으로 취급된다. storage : 검출된 외곽선의 기록을 위해 필요한 메모리 스토리지 first_contour : CvSeq*에 대한 포인터(이중포인터)로 함수 내부에서 first_contour를 자체적으로 할당 headersize : 어떤 객체를 할당할 것인지를 알려줌 mode : 어떻게 결과를 표현할 것인가를 알려주는 용도 method: 외곽선을 어떻게 근사화 할것인지 알려줌

13 외곽선 검출 mode값 내용 CV_RETR_EXTERNAL 가장 바깥쪽에 나타나는 외곽선들만 검출 CV_RETR_LIST
 내용   CV_RETR_EXTERNAL  가장 바깥쪽에 나타나는 외곽선들만 검출  CV_RETR_LIST  외곽선을 리스트로 연결.   CV_RETR_CCOMP  외곽선을 두 개의 계층으로 나누어 리스트로 관리  (바깥쪽 외곽선, 안쪽 외곽선)  CV_RETR_TREE  모든 외곽선들의 전체 계층구조를  생성 method값  내용   CV_CHAIN_CODE  프리만 체인코드를 생성  CV_CHAIN_APPROX_NONE  체인 코드의 모든 점을 꼭지점으로 변환   CV_CHAIN_APPROX_SIMPLE  수평, 수직, 대각 성분의 끝점만 저장  CV_CHAIN_APPROX_TC89_L1,   CV_CHAIN_APPROX_TC89_KCOS  Teh-Chin의 체인 근사화 알고리즘 중 하나 적용  CV_LINK_RUNS

14 외곽선 검출

15 외곽선 검출 CvSeq* cvFindNextContour(CvContourScanner scanner);
CvContourScanner cvStartFindContours(         CvArr* image,         CvMemStorage* storage,         int header_size=sizeof(CvContour),         int mode=CV_RETR_LIST,         int method=CV_CHAIN_APPROX_SIMPLE,         CvPoint offset=cvPoint(0,0) ); CvSeq* cvFindNextContour(CvContourScanner scanner); void cvSubstituteContour(CvContourScanner scanner, CvSeq* new_contour); CvSeq* cvEndFindContours(CvContourScanner* scanner); CvSeq* cvApproxChains(         CvSeq* src_seq,         CvMemStorage* storage,         int method=CV_CHAIN_APPROX_SIMPLE,         double parameter=0,         int minimal_perimeter=0,         int recursive=0 );

16 외곽선 검출 프리만 체인 void cvStartReadChainPoints(CvChain* chain, CvChainPtReader* reader);   CvPoint cvStartReadChainPoints(CvChainPtReader* reader);

17 외곽선 검출 예제 원본 영상 thresh: 100 thresh: 169 thresh: 50

18 외곽선 검출 예제 CV_CHAIN_CODE: 실행오류 발생 CV_CHAIN_APPROX_NONE
CV_CHAIN_APPROX_SIMPLE CV_RETER_TREE 상태 CV_CHAIN_APPROX_TC89_L1 CV_CHAIN_CODE: 실행오류 발생

19 CV_CHAIN_APPROX_SIMPLE 상태
외곽선 검출 예제 CV_CHAIN_APPROX_SIMPLE 상태 CV_RETER_LIST CV_RETER_TREE CV_RETER_EXTERNAL CV_RETER_CCOMP

20 using namespace cv; using namespace std; Mat src; Mat src_gray; int thresh = 100; int max_thresh = 255; RNG rng(12345); void thresh_callback(int, void* ); int main( int argc, char** argv ) { src = imread( argv[1], 1 ); cvtColor( src, src_gray, CV_BGR2GRAY ); blur( src_gray, src_gray, Size(3,3) ); char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback ); thresh_callback( 0, 0 ); waitKey(0); return(0); }

21 void thresh_callback(int, void* )
{ Mat canny_output; vector<vector<Point> > contours; vector<Vec4i> hierarchy; Canny( src_gray, canny_output, thresh, thresh*2, 3 ); findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); for( int i = 0; i< contours.size(); i++ ) Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); }

22 More to Do with Contours
다각형 근사화 외곽선을 소수의 꼭지점들로 구성된 다각형으로 만듬 OpenCV는 Douglas-Peucker 근사화 방법 사용 그외 Rosenfeld-Johnson, The-Chin 방법 등 존재 CvSeq* cvApproxPoly( const void* src_seq, int header_size, CvMemStorage* storage, int method, double eps, int recursive=0 )

23 More to Do with Contours
header_size : header size of the approximated curve. 일반적으로 sizeof(CvContour)가 사용됨 storage : memory storage where the approximated curve is stored. method : contour approximation algorithm. 현재는 only CV_POLY_APPROX_DP 가 지원됨 recursive : ㄱecursion flag ※점들을 모두 이은 선분의 크기가 지정된 값보다 작을때까지 수행

24 More to Do with Contours
Dominant Point 외곽선에 대해 더 많은 정보를 갖는 점 Dominat point 찾는 함수 CvSeq* cvFindDominantPoints( CvSeq* contour, CvMemStorage* storage, int method = CV_DOMINANT_IPAN, double parameter1 = 0, // 최소거리 double parameter2 = 0, // 최대거리 double parameter3 = 0, // 이웃과의 거리 double parameter4 = 0); // 최대각도 ) IPAN 알고리즘: contour를 따라 이동하며 이용 가능한 세개의 정점을 이용해서 곡선의 내부에 삼각형을 만드는 방식으로 작동

25 Summary Characteristics
double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 ); // 커브나 contour의 둘레를 구해주는 함수 double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ ); //contour로 둘러싸인 영역의 넓이를 계산하는 함수

26 Summary Characteristics
CvRect cvBoundingRect( CvArr* points, int update=0 ) // 외곽선을 감싸는 사각형을 CvRect형으로 반환 CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL ) // 외곽선을 감싸는 사각형을 CvBox2D형으로 반환 // 경사가 있는 사각형도 표현 가능

27 Summary Characteristics
int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius ) // 외곽선을 가장 근사화하는 타원 반환 CvBox2D cvFitEllipse2(const CvArr* points)¶

28 Summary Characteristics
CvRect cvMaxRect( const CvRect* rect1, const CvRect* rect2 ); // 두개의 입력 사각형으로 새로운 사각형 생성 void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ); // CvBox2D 구조체의 사각형의 네 꼭지점 좌표를 구함 CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* mat, CvContour* contour_header, CvSeqBlock* block ); // 행렬로부터 시퀀스 구조체 생성

29 Summary Characteristics
CvSeq* cvPointPolygonTest( const CvArr* contour, CvPoint2D32f pt, Int measure_dist ); // 어떤 한 점이 다각형내에 위치하는지 검사

30 Contour Matching 모멘트: 외곽선의 전체적인 특성을 표현하는 척도로 외곽선상에 존재하는 모든 픽셀을 이용하여 계산(3차 이하의 모멘트 계산) 외곽선 모멘트는 두 외곽선을 비교 가장 간단한 방법 void cvContourMoments( CvSeq* contour,          //외곽선         CvMoments* moments       //모멘트값이 저장될 변수 );

31 Contour Matching typedef struct CvMoments  {         double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; /* spatial moments */         double  mu20, mu11, mu02, mu30, mu21, mu12, mu03; /* central moments */         double  inv_sqrt_m00; /* m00 != 0 ? 1/sqrt(m00) : 0 */  }  CvMoments; cvContourMoments() 함수는 spatial moments만 사용하고 나머지는 다른 함수들에서 사용 double cvGetSpatialMoment(         CvMoments* moments,         int x_order,         int y_order ); // 특정 차수 모멘트 반환

32 Contour Matching 모멘트 계산: 실제 외곽선 비교시 만족스러운 성능이 나오지 않음 - 선택된 좌표계에 따라 값이 바꾸기때문에 동일한 객체도 (좌표계에 의해 회전하면) 매치가 안 되는 상황이 발생 정규화 모멘트 사용: 모양이 같고 크기가 다른 객체에 대해서도 유사한 모멘트 추출 – OpenCV는 Hue invariant moments 제공(정규화된 모멘트) - 중심 모멘트들의 선형 결합으로 구성 , 즉 서로 다른 정규화 중심 모멘트를 선형 결합함으로써 영상에 크기변환, 회전 및 반사 등이 존재하여도 모멘트 값이 변하지 않도록 만듬

33 Contour Matching void cvMoments( int binary = 0 );
const CvArr* image, CvMoments* moments,         int binary = 0 ); double cvGetCentralMoments(         int x_order,        int y_order ); double cvGetNormalizedCentralMoments(                int y_order); double cvGetHueMoments(         CvHueMoments* HuMoment);

34 Contour Matching 중심 모멘트: 정규화 모멘트: 휴 모멘트: 중심 모멘트들의 선형 결합

35 Contour Matching

36 Contour Matching 휴의 불변 모멘트를 이용한 매칭 - 두 객체를 비교하고 유사성을 판단
cvMatchShapes ( const void* object1, => 객체 1 (그레이스케일영상,외곽선) const void* object2, => 객체 2 (그레이스케일영상,외곽선) int method, double parameter = 0 )

37 Contour Matching

38 Contour Matching 외곽선 트리를 이용한 매칭 CvContourTree* cvCreateContourTree ( }
const CvSeq* contour, CvMemStorage* storage, double threshold } CvSeq* cvContourFromContourTree ( const CvContourTree* tree, CvMemStorage* storage, CvTermCriteria criteria double cvMatchContourTrees ( const CvContourTree* tree1, const CvContourTree* tree2, Int method, Double threshold

39 Contour Matching Convex Hull and Convex Defects CvSeq* cvConvexHull2 (
const CvArr* input, void* hull_storage=NULL, int orientation = CV_CLOCKWISE Int return_points = 0 }

40 Contour Matching Int* cvCheckContourConvexity (const CvArr* contour)
CvSeq* cvConvexityDefects ( const CvArr* contour, const CvArr* convexhull, CvmemStorage* storage = NULL )

41 Q & A


Download ppt "8장 Contours 2013. 09. 30 장 호욱."

Similar presentations


Ads by Google