OTSU 한도 값 분할 알고리즘 원리 와 소스 코드

2940 단어 OpenCV
OTSU 한도 값 분할
OTSU 한도 값 처리 (최대 클래스 간 분산), 알고리즘 절 차 는 다음 과 같 습 니 다. [1] 그 레이스 케 일 등급 의 모든 픽 셀 이 전체 그림 에서 의 개 수 를 통계 합 니 다.【 2 】 모든 픽 셀 이 전체 그림 에 있 을 확률 분 포 를 계산한다.【 3 】 그 레이스 케 일 등급 을 검색 하여 현재 그 레이스 케 일 값 에서 전경 배경 클래스 간 확률 을 계산 합 니 다.【 4 】 목표 함 수 를 통 해 클래스 내 와 클래스 간 의 분산 에서 대응 하 는 한도 값 을 계산한다.
그림 I (x, y), 전경 (즉 목표) 과 배경의 분할 한도 값 은 T 로 기록 하고 전경 에 속 하 는 픽 셀 포 인 트 는 전체 그림 의 비례 를 차지한다.ω0, 그 평균 그 레이스 케 일μ0;배경 픽 셀 포인트 가 전체 그림 에서 차지 하 는 비율 은?ω1. 그 평균 그 레이스 케 일 은?μ1。그림% 1 개의 캡 션 을 편 집 했 습 니 다.μ,클래스 간 방 차 는 g 로 기록 합 니 다.그림 의 배경 이 어둡다 고 가정 하고 그림 의 크기 는 M 입 니 다.×N. 그림 에서 픽 셀 의 그 레이스 케 일 값 이 한도 값 T 보다 작은 픽 셀 개 수 는 N0 으로 기록 하고 픽 셀 그 레이스 케 일이 한도 값 T 보다 큰 픽 셀 개 수 는 N1 로 기록 하면 다음 과 같 습 니 다.ω0=N0/ M×N                                            (1)       ω1=N1/ M×N                                            (2)       N0+N1=M×N                                            (3)       ω0+ω1=1                                                 (4)       μ=ω0*μ0+ω1*μ1                                     (5)       g=ω0(μ0-μ)^2+ω1(μ1-μ)^2                    (6) 장 식 (5) 대 입식 (6), 등가 공식 획득: g =ω0ω1(μ0-μ1)^2  (7)
#include 
#include 
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;

//        
int OTSU(cv::Mat srcImage)
{
    int nCols = srcImage.cols;
    int nRows = srcImage.rows;
    int threshold = 0;

    //        
    int nSumPix[256];
    float nProDis[256];
    for (int i = 0; i < 256; i++)
    {
        nSumPix[i] = 0;
        nProDis[i] = 0;
    }

    //                     
    for (int i = 0; i < nCols; i++)
    {
        for (int j = 0; j < nRows; j++)
        {
            nSumPix[(int)srcImage.at(i, j)]++;
        }
    }

    //                 
    for (int i = 0; i < 256; i++)
    {
        nProDis[i] = (float)nSumPix[i] / (nCols * nRows);
    }

    //      [0,255],               
    float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;
    double delta_max = 0.0;
    for (int i = 0; i < 256; i++)
    {
        //        
        w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;
        for (int j = 0; j < 256; j++)
        {
            //     
            if (j <= i)
            {
                //   i     ,         
                w0 += nProDis[j];
                u0_temp += j * nProDis[j];
            }
            //       
            else
            {
                //   i     ,       
                w1 += nProDis[j];
                u1_temp += j * nProDis[j];
            }
        }

        //             
        u0 = u0_temp / w0;
        u1 = u1_temp / w1;
        delta_temp = (float)(w0 *w1* pow((u0 - u1), 2));

        //                   
        if (delta_temp > delta_max)
        {
            delta_max = delta_temp;
            threshold = i;
        }
    }

    return threshold;
}




좋은 웹페이지 즐겨찾기