금일은 findContour 로 구한 외곽선 좌표정보에 적용할 수 있는 다양한 외곽선 함수에 대해서 알아본다.
위와같이 Contours 에 적용할 수 있는 다양한 함수들이 있다.
위 설명에 나오지 않은 부가적인 설명을 한다.
cv2.arcLength : 길이 계산함수인데 외곽선 좌표들로 구성되는 곡선, 폐곡선의 길이 계산
cv2. minAreaRect : 회전된 사각형의 회전된 각도도 반환
cv2.isContourConvex , convelHull, convexityDefects : Convex ( 볼록한 다각형 )
즉, 꼭지점들을 모두 둘러싸는 다각형이라고 할 수 있다.
좀 더 자세한 정보는 Open CV doucumet 사이트에서 볼 수 있다.
https://docs.opencv.org/4.x/d8/d1c/tutorial_js_contours_more_functions.html
OpenCV: Contours : More Functions
Prev Tutorial: Contour Properties Next Tutorial: Contours Hierarchy Goal Convexity defects and how to find them. Finding shortest distance from a point to a polygon Matching different shapes Theory and Code 1. Convexity Defects We saw what is convex hull i
docs.opencv.org
외곽선 길이 구하기
cv2.arcLength ( curve, closed ) ->retval
curve : 외곽선 좌표 . ( numpy.ndarray.shape=(K,1,2) )
* K : 외곽선하나의 점들의 개수 , 1 : 고정 ( 의미 X ) , 2 : X Y의 좌표
closed : True면 폐곡선으로 간주
* ( 폐곡선 : 시작점과 끝점을 이어진것으로 볼것인지
개곡선 : 시작점과 끝점을 이어지지 않은것으로 볼것인지
retval : 외곽선 길이
면적 구하기
cv2.contourArea ( contour, oriented ) -> retval
contour : 외곽선 좌표 ( numpy.ndarray.shape=(K,1,2) )
* K : 외곽선하나의 점들의 개수 , 1 : 고정 ( 의미 X ) , 2 : X Y의 좌표
oriented : True면 외곽선 진행 방향에 따라 부호 있는 면적을 반환
False면 외곽선 진행 방향과 관계없이 양수의 면적을 반환
retval : 외곽선으로 구성된 영역의 면적
바운딩 박스 ( 외곽선을 외접하여 둘러싸는 가장 작은 사각형 ) 구하기
cv2.boundingRect ( array )
array : 외곽선 좌표 ( numpy.ndarray.shape=(K,1,2) )
* K : 외곽선하나의 점들의 개수 , 1 : 고정 ( 의미 X ) , 2 : X Y의 좌표
retval : 사각형 정보. ( x, y, w, h ) 튜플
바운딩 서클 ( 외곽선을 외접하여 둘러싸는 가장 작은 원 ) 구하기
cv2.minEnclosingCircle ( points ) -> cneter, radius
points : 외곽선 좌표 ( numpy.ndarray.shape=(K,1,2) )
* K : 외곽선하나의 점들의 개수 , 1 : 고정 ( 의미 X ) , 2 : X Y의 좌표
center : 바운딩 서클 중심 좌표. ( x , y ) 튜플radius : 바운딩 서클 반지름. 실수
외곽선 근사화
cv2.approxPolyDP ( curve, epsilon, closed, approxCurve ) -> approxCurve
curve : 입력 곡선 좌표 ( numpy.ndarray.shape=(K,1,2) )
* K : 외곽선하나의 점들의 개수 , 1 : 고정 ( 의미 X ) , 2 : X Y의 좌표
epsilon : 근사화 정밀도 조절. 입력 곡선과 근사화 곡선 간의 최대 거리.
e.g) ( 외곽선 전체 길이 ) * 0.02
closed : True를 전달하면 폐곡선으로 인식
approxCurve : 근사화된 곡선 좌표 ( numpy.ndarray.shape=(K',1,2) )
출력도 똑같은 ndarray.shape , 단 K는 단순화되며 줄어들수도 있다.
참고 ( 더글라스-포이커 알고리즘 )
- 위 이미지를 참고하여 설명하면 첫번째 점과 가장 멀리 떨어져있는 점에 직선을 긋는다.
이후 그어진 직선과 가장 멀리 떨어져있는 점을 선정하여 다시 직선을 긋는다.
이후 마지막으로 그은 직선의 점과 가장 멀리 떨어져있는 직선을 선정하고 그 직선과 가장 멀리 떨어져있는 점을 선정하여
직선을 그린다.
위 과정을 반복하여 단순화된 곡선을 반환한다.
참고 : Ramer–Douglas–Peucker algorithm - Wikipedia그럼 위 알고리즘을 돌릴때 가장 중요한 것은 무엇일까?바로 마진 설정이다.
* 여기서 말하는 마진은 위 함수에 나와있는 epsilon 인자이다.보통 마진 설정은 외곽선 전체길이에 대한 비율로 설정하는데 보통 전체길이의 2% 정도를 마진으로 설정한다.
외곽선 전체길이는 위 설명에서 나왔던 arcLength 함수를 사용할 수있다.
Convex 검사
cv2.isContourConvex ( contour ) -> retval
contour : 입력 곡선 좌표. numpy.ndarray.shape = ( K, 1, 2 )
retval : 컨벡스이면 True, 아니면 Fale 반환
다각형 검출 프로그램
구현 순서
1. 이진화 ( GrayScale로 Load )
2. 외곽선 찾기
3. 외곽선 근사화
4. 너무 작은 객체와 convex가 아닌 객체 제외
5. 꼭지점 개수 확인
- 삼각형, 사각형 검출
- 원 판별
* 원 판별하기
정해진 외곽선 길이에 대한 넓이 비율이 가장 큰 형태가 원
-> 도형의 넓이 ( A ) 와 외곽선 길이 ( P )의 비율을 검사
예를들면 1m짜리의 끈으로 만들 수 있는 가장 큰 부피의 도형은 원인데
각이 들어가기 시작하면 그 면적이 조금씩 줄어들게 된다.
위 이미지에서
for pts in contours :
if cv2.contourArea( pts ) < 400:
continue
가 뜻하는 것은 contourArea 즉, 윤곽선의 부피가 400보다 작으면 무시한다는 의미이다.
노이즈를 제거하기 위한 코드라고 볼 수 있다.
이 외 설명은 생략하고 결과 영상을 보면
위와같은 결과영상을 얻을 수 있다.
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'Program > OPEN_CV' 카테고리의 다른 글
[Open CV] 영상 분할과 객체 검출 _ 모멘트 기반 객체 검출 (0) | 2022.06.13 |
---|---|
[Open CV] 영상 분할과 객체 검출 _ 그랩컷 (0) | 2022.06.12 |
[Open CV] 이진 영상 처리 _ 외곽선 검출 (0) | 2022.06.10 |
[Open CV] 이진 영상 처리 _ 레이블링 (0) | 2022.06.09 |
[Open CV] 이진 영상 처리 _ 모폴로지 _ 열기와 닫기 (0) | 2022.06.08 |