ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Global Thresholding 구현 코드
    컴공지식/컴퓨터비전 2024. 10. 2. 22:55

    전역 임계값은 이미지 전체에서 하나의 임계값(Threshold)을 설정해서, 그 임계값을 기준으로 픽셀 값을 이진화하는 기법이다.

    이 코드는 반복적으로 임계값을 조정하면서 새로운 임계값을 계산하는 방법을 보여준다.


    int main() {
        Mat image, thresh; // 이미지와 이진화된 결과 이미지를 위한 Mat 객체
        int thresh_T, low_cnt, high_cnt, low_sum, high_sum, i, j, th; // 변수들 선언

        thresh_T = 200; // 초기 임계값 설정
        th = 10; // 오차 허용 범위 (반복을 종료하기 위한 조건)
        low_cnt = high_cnt = low_sum = high_sum = 0; // 카운트 및 합 초기화

        image = imread("lena.png", 0); // 이미지를 흑백 모드로 읽어옴
        cout << "threshold value: " << thresh_T << endl; // 현재 임계값 출력

        while (1) { // 무한 루프 시작 (임계값이 안정될 때까지 반복)
            for (j = 0; j < image.rows; j++) { // 이미지의 행(row)을 순회
                for (i = 0; i < image.cols; i++) { // 각 행의 열(col)을 순회
                    if (image.at<uchar>(j, i) < thresh_T) { // 픽셀 값이 임계값보다 작은 경우
                        low_sum += image.at<uchar>(j, i); // low_sum에 픽셀 값 더함
                        low_cnt++; // low_cnt 증가
                    } else { // 픽셀 값이 임계값보다 크거나 같은 경우
                        high_sum += image.at<uchar>(j, i); // high_sum에 픽셀 값 더함
                        high_cnt++; // high_cnt 증가
                    }
                }
            }

            // 새로운 임계값 계산: 어두운 부분과 밝은 부분의 평균
            int new_thresh_T = (low_sum / low_cnt + high_sum / high_cnt) / 2;

            // 만약 임계값 차이가 설정된 범위(th) 내에 있으면 반복 종료
            if (abs(new_thresh_T - thresh_T) < th) {
                break;
            }

            // 그렇지 않으면 새로운 임계값으로 업데이트하고 다시 반복
            thresh_T = new_thresh_T;

            // 합과 카운트 초기화 (다음 루프에서 다시 계산할 수 있도록)
            low_sum = high_sum = 0;
            low_cnt = high_cnt = 0;
        }

        // 최종 임계값을 사용하여 이진화 처리
        threshold(image, thresh, thresh_T, 255, THRESH_BINARY);

        // 결과 이미지 출력
        imshow("Input image", image); // 원본 이미지 표시
        imshow("Thresholded image", thresh); // 이진화된 이미지 표시
        waitKey(0); // 키 입력 대기

        return 0;
    }

     

    이 코드는 임계값을 반복적으로 조정하면서, 이미지의 밝은 부분과 어두운 부분을 나누는 최적의 임계값을 찾아내는 방식이다.

    최종적으로 반복이 끝나면, 임계값이 안정되고 그 값을 기준으로 이진화를 할 수 있다.

     

     


     

    다음은 Otsu's Algorithm을 통한 구현이다.

    사용자가 직접 임계값을 설정하지 않아도, Otsu 알고리즘이 알아서 이미지를 흑백으로 변환할 수 있다.

     

    int main() {
        Mat image, result;
        image = imread("lena.png", 0); // 이미지를 그레이스케일로 읽어옴
        threshold(image, result, 0, 255, THRESH_BINARY | THRESH_OTSU); // Otsu 알고리즘 사용한 이진화
        
        imshow("Input image", image); // 원본 이미지 보여줌
        imshow("result", result); // 결과 이미지 보여줌
        
        waitKey(0); // 키 입력 대기
    }

     

     

    threshold(image, result, 0, 255, THRESH_BINARY | THRESH_OTSU)여기의 

    THRESH_OTSU가 Otsu 알고리즘을 사용해 최적의 임계값을 자동으로 찾아준다. 

    '컴공지식 > 컴퓨터비전' 카테고리의 다른 글

    GrabCut 함수  (0) 2024.10.02
    Local (Adaptive) Thresholding 코드 구현  (0) 2024.10.02
    inRange 함수  (0) 2024.10.02
    adaptiveThreshold 함수 코드  (0) 2024.10.02
    threshold 처리 코드  (0) 2024.10.02
Designed by Tistory.