http://lueseypid.tistory.com/80
■ 외곽선
외곽선이란 영상 내 곡선을 나타내는 점들의 리스트로 정의된다. OpenCV에서 곡선은 시퀀스를 이용하여 표현되고, 이때 시퀀스 내부에는 곡선에서 다음 점에 대한 위치 정보가 저장되어있다.
■ 외곽선 검출 - cvFindContours()
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_coutour를 자체적으로 할당하기 때문에 외부에서 사용자가 직접 할당하면 안된다.
headsize : 어떤 객체를 할당할 것인지를 알려준다.
mode : 어떤종류의 외곽선을 찾을것인가 또는 어떻게 결과를 표현할 것인가를 알려주는 용도로 사용된다.
mode값 | 내용 |
CV_RETR_EXTERNAL | 가장 바깥쪽에 나타나는 외곽선들만 검출한다. |
CV_RETR_LIST | 모든 외곽선을 검색하고 리스트에 넣는다. |
CV_RETR_CCOMP | 모든 외곽선을 검색하고 이를 두개의 계층으로 나누어 관리한다. (구성요소들의 바깥쪽 외곽선들을 연결 리스트로 관리하고, 두번째 계층에서는 구성 요소들의 안쪽 외곽선을 리스 트로 관리한다.) |
CV_RETR_TREE | 모든 외곽선들을 검색하여 외곽선들의 전체 계층구조를 생성한다. |
method : 외곽선을 어떻게 근사화 할것인지 알려준다
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 | ?? |
cvFindContours()함수는 수행후 검출된 외곽선들의 전체 개수를 반환한다.
■ cvStartFindContours()
cvStartFindContours()함수는 한번에 하나의 외곽선만 찾기 원할 때 사용된다. 이 함수는 CvContourScanner를 반환하며, CvContourScanner는 어느 시퀀스가 이미 읽혀졌는지 또는 그렇지 않은지에 대한 정보를 가지고 있다.
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) ); |
■ cvFindNextContour()
검출된 외곽선을 순차적으로 검색하며, 검색할 외곽선이 존재하지 않을경우 NULL을 반환한다.
CvSeq* cvFindNextContour(CvContourScanner scanner); |
■ cvSubstitueContour()
스캐너가 현재 가리키고 있는 외곽선을 다른 외곽선으로 대체할 때 사용된다.
void cvSubstituteContour(CvContourScanner scanner, CvSeq* new_contour); |
■ cvEndFindContour()
스캐닝이 끝난후 스캐너를 완료 상태로 설정한다.스캐너가 사용하였던 시퀀스를 삭제하지 않고, 시퀀스의 첫번째 원소에 대한 포인터를 반환한다.
CvSeq* cvEndFindContours(CvContourScanner* scanner); |
■ cvApproxChains()
프리만 체인을 정확하게 또는 근사화하여 다각형 표현방식으로 표현한다.
CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0 ); |
■ 외곽선 그리기 - cvDrawContours()
void cvDrawContours( CvArr *img, CvSeq* contour, CvScalar external_color, CvScalar hole_color, int max_level, int thickness=1, int line_type=8, CvPoint offset =cvPoint(0,0) ); |
contours : 외곽선 트리의 루트 노드
external_color : 외부 외곽선의 색상
hole_color : 홀의 외곽선(내부 외곽선)의 색상
max_level : 외곽선을 그릴때 이동할 최대깊이
thickness, line_type : 외곽선의 굵기와 타입
offset : 외곽선이 그려질 위치를 지정하는 용도로 사용
#include <cv.h> #include <highgui.h>
IplImage* g_image=NULL; IplImage* g_gray=NULL; IplImage* g_binary=NULL; int g_thresh=100; CvMemStorage* g_storage=NULL;
void on_trackbar(int pos) {
if(g_storage==NULL) { g_gray=cvCreateImage(cvGetSize(g_image), 8, 1); g_binary=cvCreateImage(cvGetSize(g_image), 8, 1); g_storage=cvCreateMemStorage(0); } else { cvClearMemStorage(g_storage); }
CvSeq* contours=0;
//g_image영상을 BRG색공간을 그레이 스케일로 변환(BGR to Gray = BGR2GRAY) cvCvtColor(g_image, g_gray, CV_BGR2GRAY);
//임계값 이하:0, 임계값초과값:1 설정 cvThreshold(g_gray, g_gray, g_thresh, 255, CV_THRESH_BINARY); cvCopy(g_gray, g_binary);
//윤곽선 찾기 cvFindContours( g_gray, //입력영상 g_storage, //검출된 외곽선을 기록하기 위한 메모리 스토리지 &contours, //외곽선의 좌표들이 저장된 Sequence sizeof(CvContour), CV_RETR_TREE //어떤종류의 외곽선 찾을지, 어떻게 보여줄지에 대한정보 );
cvZero(g_gray); if(contours) { //외곽선을 찾은 정보(contour)를 이용하여 외곽선을 그림 cvDrawContours( g_gray, //외곽선이 그려질 영상 contours, //외곽선 트리의 루트노드 cvScalarAll(255), //외부 외곽선의 색상 cvScalarAll(128), //내부 외곽선의 색상 100 //외곽선을 그릴때 이동할 깊이 ); }
cvShowImage("Original", g_image); cvShowImage("Binary", g_binary); cvShowImage("Contours", g_gray); }
int main(int argc, char** argv) { if(argc!=2 || !(g_image=cvLoadImage(argv[1]))) return -1;
cvNamedWindow("Original", 1); cvNamedWindow("Binary", 1); cvNamedWindow("Contours", 1); cvCreateTrackbar("Threshold", "Contours", &g_thresh, 255, on_trackbar); on_trackbar(0);
cvWaitKey();
cvReleaseImage(&g_image); cvReleaseImage(&g_gray); cvReleaseMemStorage(&g_storage); cvDestroyWindow("binary"); cvDestroyWindow("Contours"); return 0; } |
출력결과
'차근차근 > OpenCV' 카테고리의 다른 글
배경제거 (0) | 2014.08.05 |
---|---|
모멘트 - 외곽선의 유사도 비교 (0) | 2014.08.05 |
메모리 스토리지 (0) | 2014.08.05 |
임계값(Threshold) (0) | 2014.08.05 |
시퀀스(Sequence) (0) | 2014.08.05 |