지역 이진화
지난 포스팅에서 Otsu 함수를 통해 임계값을 자동으로 결정하고 이미지를 이진화하는 방법에 대해서 알아보았다.
단순히 Otsu를 적용하는 것으로 객체와 배경을 분리할 수 있으면 좋겠지만 현실은 그렇지 않다.
다음의 쌀알이 포함된 이미지를 살펴보자.
쌀알 이미지에 Otsu 함수를 적용하면 다음과 같은 이진화 된 이미지를 얻을 수 있다.
큰 문제는 없어보인다. 다만 이미지 하단부의 빨간색으로 마킹해놓은 여역을 살펴보면 쌀알이 제대로 나타나지 않는다.
이유는 사진(이미지)를 찍을 때 균일하지 않은 조명의 영향을 받기 때문에다. 위의 쌀알 이미지를 예로 들어 설명하면, 전체적인 밝기에 비해 이미지 하단부가 조금 어둡기 때문에 동일한 임계값으로 threshold를 적용했을 때 객체가 분리되지 않는 것이다
아래의 내용 처럼 지역 이진화를 통해 이 문제를 해결해보자.
- 이미지내의 영역을 임의로 분할 한다 (m*n)
- 분할된 영역에 대해 이진화를 진행한다 -> 지역 이진화
지역 이진화를 진행하면 영역을 잘게 쪼개기 때문에 균일하지 않은 배경의 밝기에 대해서 좀 더 둔감해지는 효과가 있다. 그렇기 때문에 Otsu 알고리즘을 통한 임계값 결정 시 조금 더 나은 결과를 얻을 수도 있다.
지역 이진화 예제
예제코드를 살펴보자.
val graySrc = ... // 이미지의 사이즈 val width = graySrc.width() val height = graySrc.height() // 이미지내에서 m*n으로 영역을 나눈다. for (row in 0 until rows) { for (column in 0 until columns) { val submat = graySrc.submat( height / rows * row, height / rows * (row + 1), width / columns * column, width / columns * (column + 1) ) // 나눠진 영역에 대해 개별적으로 Otsu 이진화 적용 Imgproc.threshold( submat, submat, 0.0, 255.0, Imgproc.THRESH_BINARY or Imgproc.THRESH_OTSU ) } } // graySrc 출력
쌀알 이미지를 4*4 영역으로 나누어 Otsu를 진행해보았다.
Otsu로 이미지 전체를 이진화 했을 때보다, 영역을 분할하여 지역 이진화를 했을 때 더 나은 결과물을 얻은 것을 확인할 수 있다.
실패 사례
하지만 지역 이진화가 항상 좋은 결과를 가져오는 것은 아니다. 다음 나오는 실패한(?) 이진화 이미지들을 살펴보자.
왼쪽부터 원본 이미지, Otsu 적용 된 이미지, 지역 이진화 된 이미지다.
Otsu가 적용 된 이미지는 배경의 밝기 차이때문에 왼쪽 하단이 객체가 잘 검출되지 않았고,
4*4로 진행된 지역 이진화는 오른쪽 상단의 영역에 Otsu를 적용했을 때 상대적으로 밝은 배경 때문에 적절한 임계값이 설정되지 못한 것을 확인할 수 있다. 적응형 이진화를 통해 이 문제를 해결해보자.
0개의 댓글