2015년 7월 6일 월요일

제1장) Open CV를 이용한 사각형 검출

사각형 검출하는 방법은 다음과 같이 구성하였다.

1) 영상의 원본을 불러온다. (변수  = frame)
2) 영상의 RGB값을 Gray scale화 한다. (변수 = gray)
3) Gray scale 한 값을 이진화한다.(나는 이진화 inverse 를 이용하였다.)
4) 이진화한 영상을 Canny Edge 검출을 하고  외곽선(윤곽선)을 추출한다.
5) 추출한 외곽선을 근사화 시킨다.
6) 만약  근사화한 외곽선의 코너가 4개이면 사각형이라 판단하고 각각의 꼭지점을 구한다.
7) 꼭지점을 구했으니 변의길이도 알수 있고 추가로 영상에 boxing하여 나타낼수 있게된다.




그럼 직접 코드를 보며 해보자.
IplImage* frame = 0;        //기본 윈도우 frame 설정
IplImage* Output = 0;        //이진화 
IplImage* Output_inverse = 0;        //역이진화
IplImage* gray = 0;            //grayscale된후의 결과
IplImage* Result = 0;            //추출된 값
IplImage* HSV = 0;
CvMat *mask,*mask_board;
CvSize size;
cs

영상을 gray scale화 하고 이진화한 방식과 역이진화한 방식 둘다 해보았다.

//    cvNamedWindow("binary", 0);            //이진화 윈도우 설정
    cvNamedWindow("Check Board"0);        //역이진화 윈도우 설정
    cvNamedWindow("Black Tracking"0);    // 트래킹 윈도우 설정
    cvNamedWindow("Gray Scale"0);        //Gray Scale 윈도우 설정
    cvNamedWindow("Result"0);            //추출 윈도우 설정
    cvNamedWindow("HSV",0);                //HSV 변환
    cvCreateTrackbar("T""binary"&threshold, 255NULL);    //window 'Output' 의 트랙바 설정
    if (argc == 1) {
        capture = cvCreateCameraCapture(0);    //카메라가 한대있으면 0(anycamera) 여러대있을경우 ++1을 해준다.
    }
    assert(capture != NULL);    //assert란 주어진 조건이 거짓이면 오류메시지와 코어덤프를 출력하고 종료한다
    // 코어 덤프란 실행중인 프로그램에 대한 정보를 core라는 이름으로 파일로저장하는것
    while (1) {
        frame = cvQueryFrame(capture);    //cvGrabFrame() , cvretrieveFrame() 함수들을 결합해놓은 함수
        
        if (cvWaitKey(10>= 0break;
        if (!frame) break;
        if (!Output){
            gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
            Output = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
            Output_inverse = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
            Result = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
            HSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
        }
        cvZero(Result);                //결과값의 Image data 0 => Black 화면 설정
        size = cvGetSize(frame);
        cvSmooth(HSV, HSV, CV_GAUSSIAN, 55);    //스무딩 MAX (5,5)
        cvCvtColor(frame, HSV, CV_RGB2HSV);        //RGB색을 HSV 변환
        cvCvtColor(frame, gray, CV_RGB2GRAY);    //RGB색을 GrayScale 변환
        
        cvThreshold(gray, Output, threshold, 255, CV_THRESH_BINARY);    //(입력값,결과값,임계값,임계값 최대치,이진화방식) 
        cvThreshold(gray, Output_inverse, threshold, 255, CV_THRESH_BINARY_INV);    //(입력값,결과값,임계값,임계값 최대치,역이진화방식)
        mask_board = cvCreateMat(size.height, size.width, CV_8UC1);
        cvInRangeS(HSV, cvScalar(00198)
            , cvScalar(9080255), mask_board);    //HSV범위내의 이미지를 masking
        cvCopy(mask_board, Output_inverse, NULL);    //(원본,결과,mask) Output_inverse(Check Board)영상에 복사
        //Morphology - Opening (잡영제거)
        cvErode(mask_board, mask_board, NULL);        //침식
        cvDilate(mask_board, mask_board, NULL);        //팽창
        .....
cs


그 후에 Canny Edge검출로 결과영상에 저장을하였다.
cvCanny(Output_inverse, Result, 252003);        //원본,결과,low Threshold,high Threshold , 필터크기
                                                            //결과 Result에 저장
cvFindContours(Result, storage, &contour, sizeof(CvContour), 12, cvPoint(00));
        
cs

마지막으로 각각의 꼭지점을 검출하여 꼭지점부분에 원과 사각형을 결과영상에 그려넣었다.
추가로 cvPutText함수도 사용하여 꼭지점마다의 좌표를 영상에 넣었다.
결과 영상은 다음과같다. 

바둑판이 너무커서 임시로 작은 사각형을 판별해보았다.
아주 잘된다.
다음은 원검출에대한 포스트를 올리도록 하겠다.

원본 이미지가 없어졌네요 ㅠㅠ 

코드는 이곳에 있는 코드를 참고해주세요.

바둑알, 바둑판 인식 되는 코드입니다.

댓글 없음:

댓글 쓰기