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

Slides:



Advertisements
Similar presentations
YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
Advertisements

Vision System Lab, Sang-Hun Han
이정훈 전한배. 1. What is Image Processing? 2. Image Making 3. Application 4. OpenCV Outline.
제 11 장 구조체.
CUDA & OpenCV Programming
C++ Espresso 제3장 배열과 포인터.
Snake : Active Contour Model Computer Vision & Pattern Recognition
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제1장 기초 사항.
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
제 2 장 배열과 스트링.
알고리즘(Algorithm)  알고리즘 개요 (효율, 분석, 차수) Part 1 강원대학교 컴퓨터과학전공 문양세.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
OpenCV 설치 OpenCV 3.0, Visual Studio 2010 환경.
CHAP 6:큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
8. 객체와 클래스 (기본).
C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제18장 입출력과 라이브러리 함수 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
연결리스트 (Linked List) 충북대학교 컴퓨터공학과 서 영 훈.
Red Color Detection Course ChanYoung Kim
배열, 포인터, 참조 배열은 같은 형을 가지는 변수들의 묶음이다..
Multimedia Programming 9: Text, Mouse Callback and Drawing
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
head data link data link data link NULL a b c
자료 구조: Chapter 3 (2)구조체, 포인터
CHAP 6:큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
Red Color Detection Course ChanYoung Kim
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 03. 클래스의 기본.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
25장. 메모리 관리와 동적 할당.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
[INA240] Data Structures and Practice
3장. 포인터, 배열, 구조체 포인터, 배열, 구조체 학습목표 기본적 데이터 타입
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
14장. 함수 1 01_ 함수의 기본 02_ 인자의 전달.
14주차.
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
Dongchul Kim / / OpenCV Tutorials Course Dongchul Kim / /
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
OpenCV Tutorials Dongchul Kim Media System Lab., Yonsei University
Chapter 3 클래스. 최호성.
Multimedia Programming 10: Unsharp Masking/ Histogram Equalization
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
OpenCV 설치 및 구성 OpenCV
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
알고리즘(Algorithm)  알고리즘 개요 (효율, 분석, 차수) Part 년 봄학기
Chap. 1 Data Structure & Algorithms
박정식 심규동 OpenCV 기초 박정식 심규동
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
프로그램 운영기간 : 3D 프린팅 실습 : ~ (과학관256) 3D 프린팅 회사 견학 및 실습 : 7월 초
OpenCV 가족구성에 따른 TV 구매 방향 - Graphic Therapy : 도형 심리 검사 ( 사용자가 도형을 그리면, 그려진 도형의 위치와 크기 겹쳐진 형태에 따라 조건에 맞게 판별. 실제 검사와 근사한 결과가 나오도록 하는 데 중점을 둠.)
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
조 병 규 Software Quality Lab. 한 국 교 통 대 학 교
C89(C++03) 프로그래밍 (Part 2) 7 배열 8 변수 범위 9 포인터 10 유도 자료형.
5. 논리적 자료표현 : 구조체.
nauten Compiler – Report Ver.3 Mini-C (주간)
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
16장. 컴퓨터 구조에 대한 네 번째 이야기 작성자: 윤성우.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
포인터와 배열 조 병 규 한 국 교 통 대 학 교 SQ Lab..
Chapter 9. Multilevel Indexing and B-Trees
자료구조 세미나 발표 주제: 자료구조 기초 - 1회 차: 자료구조의 정의, 기초 지식 (함수, 포인터, 레퍼런스)
컴퓨터 프로그래밍 기초 - 11th : 파일 입출력 및 구조체 -
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
C.
배열, 포인터, 함수 Review & 과제 1, 2.
Presentation transcript:

8장 Contours 2013. 09. 30 장 호욱

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

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

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) // 메모리 버퍼 할당

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;

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); // 특정 원소의 위치 파악

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

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

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

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)

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

외곽선 검출 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: 외곽선을 어떻게 근사화 할것인지 알려줌

외곽선 검출 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  

외곽선 검출

외곽선 검출 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 );

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

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

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

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

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

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

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 )

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 ※점들을 모두 이은 선분의 크기가 지정된 값보다 작을때까지 수행

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를 따라 이동하며 이용 가능한 세개의 정점을 이용해서 곡선의 내부에 삼각형을 만드는 방식으로 작동

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로 둘러싸인 영역의 넓이를 계산하는 함수

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

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

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 ); // 행렬로부터 시퀀스 구조체 생성

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

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

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 ); // 특정 차수 모멘트 반환

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

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

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

Contour Matching

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

Contour Matching

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

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

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

Q & A