사각형 검출하는 방법은 다음과 같이 구성하였다.
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, 255, NULL); //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) >= 0) break;
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, 5, 5); //스무딩 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(0, 0, 198)
, cvScalar(90, 80, 255), 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, 25, 200, 3); //원본,결과,low Threshold,high Threshold , 필터크기
//결과 Result에 저장
cvFindContours(Result, storage, &contour, sizeof(CvContour), 1, 2, cvPoint(0, 0));
| cs |
댓글 없음:
댓글 쓰기