지역 이진화

지난 포스팅에서 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를 적용했을 때 상대적으로 밝은 배경 때문에 적절한 임계값이 설정되지 못한 것을 확인할 수 있다. 적응형 이진화를 통해 이 문제를 해결해보자.

 

 

카테고리: OpenCV

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.