最大熵分割法

最大熵分割法

主要的熵算法有P氏熵算法、KSW熵算法、JM熵算法。本文以KSW熵算法威力,介绍其原理和计算过程。


KSW 熵算法

设分割阈值为 tL1i=0Pi=1Pi0 .

Ti{0,1,,t} 的分布,B为i{t+1,,L1} 的分布,具体形式为:

TP0Pn,,PtPn

BPt+11Pn,,PL11Pn

其中 Pn=ti=0Pi .

则两个概率分布的熵为:

H(T)=i=0tPiPnlnPiPn

H(B)=i=t+1L1Pi1PnlnPi1Pn

定义函数 ϕ(t)H(T)H(B) 的和,则

ϕ(t)=H(T)+H(B)

阈值分割的门限值 targtmaxϕ(t) .


代码

#include <cv.h>
#include <opencv2/opencv.hpp>  
#include <opencv2/legacy/legacy.hpp>
using namespace cv;

float calc_entropy(CvHistogram *hist, int begin, int end)
{
    float total = 0;  // 总概率
    // 得到总的Pi
    for(int i = begin; i < end; i++)
    {
        total += cvQueryHistValue_1D(hist,i);
    }

    float entropy = 0;  // 熵

    for(int i = begin; i < end; i++)
    {
        float probability = cvQueryHistValue_1D(hist, i);
        if(probability == 0)
            continue;
        probability /= total;

        entropy += -probability*log(probability);
    }

    return entropy;
}

int ksw_entropy(IplImage *img)
{
    assert(img != NULL);
    assert(img->depth == 8);  
    assert(img->nChannels == 1);  

    float range[2] = {0,255};
    float *ranges[1] = {&range[0]};
    int sizes = 256;

    // 创建直方图
    CvHistogram *hist = cvCreateHist(1, &sizes, CV_HIST_ARRAY, ranges, 1);
    // 直方图计算
    cvCalcHist(&img, hist, 0, 0);
    // 直方图归一化
    cvNormalizeHist(hist, 1.0); 

    int threshold = 0;
    float max_entropy = 0;
    // 循环计算,得到做大熵以及分割阈值
    for(int i = 0; i < sizes; i++)
    {
        float entropy = calc_entropy(hist, 0, i) + calc_entropy(hist, i+1, sizes);
        if(entropy > max_entropy)
        {
            max_entropy = entropy;
            threshold = i;
        }
    }

    return threshold;
}
int main(int argc, char **argv)
{
    IplImage *img = cvLoadImage("1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    IplImage *reimg = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);

    int threshold = ksw_entropy(img);
    cvThreshold(img, reimg, threshold, 255, CV_THRESH_BINARY); 

    cvNamedWindow("img");
    cvShowImage("img", img);
    cvNamedWindow("reimg");
    cvShowImage("reimg", reimg);

    cvWaitKey(0);
    return 0;
}

原图
原图


分割图
分割图

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页