본문 바로가기

# 미사용/OpenCV

[OpenCV] 이진화 (1) BINARY, BINARY_INV


 이진화 (Binarization)

기준값 (=문턱, threshold)을 정한 뒤.

문턱보다 작은 값은 0으로, 큰 값은 1로 변환하는 것.

0~255 범위를 두가지 값으로 바꾸는 작업이므로 이진화라고 부른다.




figure 1 )

다음은 정수배열을 이진화하는 작업을 보여준다.

그레이스케일 (= 1채널 영상)은 양수배열과 같으므로, 다음 그림처럼 동작한다.





figure 2)

다음은 RGB (= 3채널 영상)의 이진화 작업을 보여준다.

그레이스케일(=RGB값의 평균)로 변환한 뒤에 이진화를 수행한다.


이미지 프로세싱은 검정 또는 흰색이므로,

실제 값은 0 또는 255로 변환된다.


[출처]  https://poorman.tistory.com/143




 왜 이진화가 필요한가?

  • 빠른 영상처리

3채널 영상은 한 픽셀당 (255^3)개의 상태를 갖지만,

이진화된 1채널 영상은 2개의 상태만 갖기 때문에 영상처리가 빨라진다.



  • 물체 마스크 획득

어떤 사진에서 물체의 형태를 획득할 수 있다.


좌측 그림에서 흰색을 검정으로, 나머지를 흰색으로 바꾸면

사과 모양의 마스크 이미지를 획득할 수 있다. 




 threshold 함수

def )

/**
 * 입력 영상에 대해 이진화를 수행한다.
 * 
 * @param src               입력 이미지
 * @param dest              결과가 저장될 곳
 * @param thres             문턱 값
 * @param max_val           문턱을 넘기면 바뀔 값
 * @param threshold_type    이진화 알고리즘 선택
 * @return 
 *      OSTU 이진화 알고리즘을 선택했을 때,
 *      해당 알고리즘이 선택한 최적의 thres 값.
 */
double threshold(
        Mat src,
        Mat dest,
        double thres, 
        double max_val, 
        int threshold_type 
);



basic threshold type )

  • BINARY 타입은 0 또는 1만 갖는다.

  • TRUNCATE 타입은 이전값을 유지할 수 있다.

  • TO ZERO 타입은 이전값을 유지하고, 임계를 넘기면 0으로 변한다.

  • 뒤에 INV가 붙으면, 양쪽의 기준이 반전된다.





 OpenCV 로고 마스크 예제

original image )





step 1)

그레이 스케일로 이미지를 불러온다.

Mat image_ch1 = imread("./images/opencv.png", IMREAD_GRAYSCALE);
CV_Assert(image_ch1.data);
imshow("image_ch1", image_ch1);





step 2)

검은색 배경 마스크를 얻어보자.

0보다 크면 255로, 작으면 0으로 이진화하면 된다.

//! 배경이 검정색이 되도록 이진화한다.
Mat image_mask_black_bg_ch1;
threshold(image_ch1, image_mask_black_bg_ch1, 0, 255, THRESH_BINARY);
imshow("image_mask_black_bg_ch1", image_mask_black_bg_ch1);



step 3)

흰색 배경 마스크를 얻어보자.

0보다 크면 0으로, 작으면 255으로 이진화하거나,

검정배경 마스크에 NOT 연산을 취하면 된다.

//! 배경이 흰색이 되도록 이진화한다.
Mat image_mask_white_bg_ch1;
/*
 * threshold(image_ch1, image_mask_white_bg_ch1, 0, 255, THRESH_BINARY_INV);
 * 또는
 * bitwise_not(image_mask_black_bg_ch1, image_mask_white_bg_ch1);
 */
imshow("image_mask_white_bg_ch1", image_mask_white_bg_ch1);