사각형, 원, 별표 등 이미지에서 도형 감별하기. 사실 명확하게 그려져 있는 샘플이미지에서
정확도가 높다. 사진 등에선 정확도가 매우 떨어지기에 이미지 전처리를 잘 하여야 한다.
씬 이름 : Identify_Contours_by_Shape
1. 기본 흐름
- 이미지를 grayscale로 변환한다
- threshold를 이용하여 흑백으로 변환한다. 이때 사용되는것이 임계값인데, 임계값 미만이면 0,
임계값 초과면 설정값으로 변경하여 흑백으로만 구분한다.
- 흑백으로 구분된 이미지에서 외각선을 찾는다.
- 찾은 외각선을 그리기 위해 필요한 최소의 포인트를 구해낸다
- 즉, 찾은 외각선을 다시 그리기 위해 최소 점을 구한다. 사각형을 그리는데에는 4개의 점만 있으면 되는데
결과값이 20개가 나왔다면, 4개로 줄이는 작업을 한다.
- 포인트 array 개수에 따라 삼각형, 사각형, 별 등 으로 구분을 하고, 색을 넣어서 이미지를 그린다
- 여기서 사용되는것은 Scalar 이며, 인자값이 3개이다. RGB가 아니라 BGR이다.
- 그린 이미지를 화면에 표시한다.
2. 상세
- 이미지로딩, grayscale로 변경
Mat image = Unity.TextureToMat (this.texture);
Mat grayMat = new Mat();
Cv2.CvtColor (image, grayMat, ColorConversionCodes.BGR2GRAY);
- 이미지를 흑백으로 변경
- 127을 넘는 값은 255로, 그 미만은 0으로 처리한다.
- ThresholdType에 따라 결과가 다르다. Binary, Binaryinv, Trunc, Tozero, Tozero_inv 가 있다.
- Binary는 흑백으로만 구분하는것이고, Trunc 는 흑을 그라데이션 처리, 흰색은 그대로 처리
- TopZero 는 흑은 그대로 처리, 백은 그라데이션
Mat thresh = new Mat ();
//127을 넘는 값은 255로 하고, 넘지않으면 0으로 처리함으로서 흑백으로 변환한다
//ThresholdTypes.BinaryInv 는 흑백을 0과 1로 처리한 후, 이 값을 반전시킨것을 의미한다.
Cv2.Threshold (grayMat, thresh, 127, 255, ThresholdTypes.BinaryInv);
- 경계선 찾기 (Cv2.FindContours)
- RetrivalModes : 경계선 찾는 방법
- External : 가장 바깥쪽 라인만 찾기
- List : 모든 경계선을 찾으나, 하이어라키를 구성하지 않음
- CCOMP : 모든 경계선을 찾고, 하이어라키를 2레벨로 구성
- TREE : 모든 경계선을 찾고 모든 하이어라키를 구성
- ContourApproximationModes : 경계선을 찾을때 사용하는 근사치 방법
- None : 모든 포인트를 저장
- simple : 경계선을 그릴수 있는 포인트만 저장 (예 : 4각형은 4개)
- tc89_L1, TC89_KCOS : 포인트를 찾는 알고리즘..
Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours (thresh, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone, null);
- 찾은 경계선을 반복문을 돌리고, 각 경계선을 다시 그리고, 포인트 갯수별 도형감지 및 그리기
- ArcLength 함수 : 경계선의 길이를 리턴. 인자값은 폐곡선인지 여부
- ApproxPolyDP 함수 : 경계선을 그리기 위해 필요한 최소한의 점 수를 계산한다.
- 두번째 인자값 : 앱실론. 오차를 뜻하며, 값이 작을수록 오차범위를 줄여 원래 도형에 가깝게 그려낸다.
- 세번째 인자값 : 폐곡선 여부를 설정한다.
- ApproxPolyDP 의 리턴 배열의 갯수가 3개이면 3각형, 4개이면 사각형...... 으로 판별한다.
- DrawContours : 경계선 그리기
- 2번째 인자값 : 그릴 경계선의 포인트 데이터
- 3번째 인자값 : 2번째 인자값의 인덱스값 지정.
- 마지막 인자값 : 경계선 라인 두께
double length = Cv2.ArcLength(contour, true);
Point[] approx = Cv2.ApproxPolyDP(contour, length * 0.01, true);
......
Cv2.DrawContours(image, new Point[][] {contour}, 0, color, -1);
'OpenCV' 카테고리의 다른 글
Opencv+Unity 이용하여 문서인식 앱 만들기 (0) | 2022.04.12 |
---|---|
[Unity] Unity+OpenCV 문서 인식 하기 (0) | 2022.04.01 |
[Unity] OpenCV+Unity 사진에서 인물 감별 (0) | 2022.03.29 |
[Unity] Opencv+Unity 얼굴 인식부위에 이미지 넣기 (0) | 2022.03.29 |
[Unity] Opencv+Unity 어셋 얼굴인식 (0) | 2022.03.28 |