Prerequisite : 윤곽선 길이 구하기, Convex hull
볼록 결함 찾기
지난 시간에 Convex hull에 대해서 알아보았다. 이 포스팅에서는 볼록 결함(convexity defect)를 찾는 방법에 대해서 알아본다.
볼록 결함이란 convex hull로 부터 오목하게 들어간 윤곽선 중 가장 멀리 떨어진 부분을 찾는 방법이라고 할 수 있다.
자세한 내용은 stackoverflow의 한 답변으로 대체한다.
OpenCV에서는 이 볼록 결함을 찾기위해 convexityDefects라는 함수를 제공한다.
Imgproc.convexityDefects(contour, convexHull, convexityDefects)
contour: 윤곽선 좌표 정보
convexHull: convex hull 정보
convexityDefects: 함수 호출 후 참조 할 볼록 결함 정보
Convex hull 포스팅에서 다뤘던 손 모양 예제를 수정하여 넣어볼록 결함을 찾아보자.
예제코드:
val contours = ArrayList<MatOfPoint>() val hierarchy = Mat() //윤곽선 검출 Imgproc.findContours( binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE ) for (i in 0 until contours.size) { // 윤곽선 근사화, (근사화 하지 않으면 의도했던 결과보다 많은 볼록결함이 발견된다) val contour2f = MatOfPoint2f(*contours[i].toArray()) val approxContour = MatOfPoint2f() Imgproc.approxPolyDP( contour2f, approxContour, Imgproc.arcLength(contour2f, true)*(0.005), true ) val convexHull = MatOfInt() // 컨벡스 헐 찾기 val contour = MatOfPoint(*approxContour.toArray()) Imgproc.convexHull(contour, convexHull) // 컨벡스 헐 정점만 추려내기 val contourArray: Array<Point> = contour.toArray() val hullPoints: Array<Point?> = arrayOfNulls<Point>(convexHull.rows() val hullContourIdxList = convexHull.toList() for (j in hullContourIdxList.indices) { hullPoints[j] = contourArray[hullContourIdxList[j]] } // 처음에 검출한 윤곽선 정보를 토대로 그리기 Imgproc.drawContours(src, contours, i, RED) // 컨벡스 헐 정보를 토대로 그리기 Imgproc.drawContours(src, listOf(MatOfPoint(*hullPoints)),0, GREEN) // 볼록결함 찾기 val convexDefects = MatOfInt4() Imgproc.convexityDefects(contour, convexHull, convexDefects) val convexDefeatList = convexDefects.toList() val vertexArray = contour.toArray() for(j in 0 until convexDefeatList.size step 4){ val start = vertexArray[convexDefeatList[j]] val end = vertexArray[convexDefeatList[j+1]] // 컨벡스 헐의 시작점(start)과 끝점(end) 사이의 볼록결함 val def = vertexArray[convexDefeatList[j+2]] Imgproc.circle(src, def, 5, BLUE, 2) } }
0개의 댓글