지금까지 설명한 외곽선 처리 함수를 이용하여 영상에서 다양한 다각형을 검출하고 인식하는 예제 프로그램을 만들어 보겠습니다. 코드 12-5에 나타난 프로그램은 입력 영상을 이진화하여 객체 영역을 모두 검출하고, 검출한 객체의 외곽선 정보를 이용하여 삼각형, 사각형, 원을 판단하여 화면에 표시합니다. 코드 12-5에 나타난 소스 코드 파일과 사용된 영상 파일은 내려받은 예제 파일 중 ch10/polygon 프로젝트에서 확인할 수 있습니다.
코드 12-5 다각형 검출 및 인식 예제 [ch10/polygon]
01 #include "opencv2/opencv.hpp" 02 #include <iostream> 03 04 using namespace cv; 05 using namespace std; 06 07 void setLabel(Mat& img, const vector<Point>& pts, const String& label) 08 { 09 Rect rc = boundingRect(pts); 10 rectangle(img, rc, Scalar(0, 0, 255), 1); 11 putText(img, label, rc.tl(), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255)); 12 } 13 14 int main(int argc, char* argv[]) 15 { 16 Mat img = imread("polygon.bmp", IMREAD_COLOR); 17 18 if (img.empty()) { 19 cerr << "Image load failed!" << endl; 20 return -1; 21 } 22 23 Mat gray; 24 cvtColor(img, gray, COLOR_BGR2GRAY); 25 26 Mat bin; 27 threshold(gray, bin, 200, 255, THRESH_BINARY_INV | THRESH_OTSU); 28 29 vector<vector<Point>> contours; 30 findContours(bin, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); 31 32 for (vector<Point>& pts : contours) { 33 if (contourArea(pts) < 400) 34 continue; 35 36 vector<Point> approx; 37 approxPolyDP(pts, approx, arcLength(pts, true)*0.02, true); 38 39 int vtc = (int)approx.size(); 40 41 if (vtc = = 3) { 42 setLabel(img, pts, "TRI"); 43 } else if (vtc = = 4) { 44 setLabel(img, pts, "RECT"); 45 } else if (vtc > 4) { 46 double len = arcLength(pts, true); 47 double area = contourArea(pts); 48 double ratio = 4. * CV_PI * area / (len * len); 49 50 if (ratio > 0.8) { 51 setLabel(img, pts, "CIR"); 52 } 53 } 54 } 55 56 imshow("img", img); 57 58 waitKey(0); 59 return 0; 60 }