Prerequisite : 윤곽선 길이 구하기
fitLine 함수
OpenCV에서는 fitLine이라는 함수를 제공하는데, 이는 주어진 점들을 적당히 감싸는 직선 정보를 구할 수 있다.
fitLine 함수는 ∑iρ(ri)를 최소화하여 2D 또는 3D 점들의 집합에 선을 피팅하는데, 여기서 ri는 i번째 점과 선 사이의 거리이고, ρ(r)은 거리를 구하는 함수다.
거리를 구하는 함수의 종류는 다음과 같다.
- DIST_L2: ρ(r)=r2/2, 가장 간단하고 빠른 최소제곱법
- DIST_L1: distance = |x1-x2| + |y1-y2|
- DIST_C: distance = max(|x1-x2|,|y1-y2|)
- DIST_L12: L1-L2 metric: distance = 2(sqrt(1+x*x/2) – 1))
- DIST_FAIR: distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
- DIST_WELSCH: distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
- DIST_HUBER: distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
fitLine 함수의 매개변수에 대해서 살펴보자
Imgproc.fitLine(contour, line, distType, param, reps, aeps)
contour: 윤곽선 정보, 2D 또는 3D 좌표의 벡터값
line: 함수 호출 후 참조 가능한 Mat 타입의 선분 정보
distType: 거리를 구하는 함수 타입
param: 일부 distType에 대한 수치 매개변수( C ), 0이면 최적의 값이 선택된다.
reps: 반경에 대한 충분한 정확도(좌표 원점과 선 사이의 거리)
aeps: 각도에 대한 충분한 정확도. reps와 aeps에 대해 좋은 기본값은 0.01이다.
fitLine 함수를 통해 이미지내 윤곽선에 적합한 직선을 구하는 예제를 살펴보자.
예제코드:
val contours = ArrayList<MatOfPoint>() val hierarchy = Mat() // 윤곽선 좌표 구하기 Imgproc.findContours( binary, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE ) for (i in 0 until contours.size) { val contour2f = MatOfPoint2f(*contours[i].toArray()) val line = Mat() // 주어진 점들에 대해 적합한 선분 정보 구하기 Imgproc.fitLine(contour2f, line, Imgproc.DIST_L2, 0.0, 0.01, 0.01) // 단위 벡터 val vx = line.get(0, 0)[0] val vy = line.get(1, 0)[0] // 직선위의 점 val x = line.get(2, 0)[0] val y = line.get(3, 0)[0] // 이미지 경계부근까지 연장한 후 빨간색으로 그림 val lefty = (-x * vy / vx + y).roundToInt().toDouble() val righty = ((src.cols() - x) * vy / vx + y).roundToInt().toDouble() val point1 = Point((src.cols() - 1).toDouble(), righty) val point2 = Point(0.0, lefty) Imgproc.line(src, point1, point2, RED) }
0개의 댓글