最大熵阈值分割

来源:互联网 发布:淘宝网吧二手电脑 编辑:程序博客网 时间:2024/06/05 04:08

现在主要用的熵算法有 P 氏熵算法,KSW 熵算法、JM 熵算法下面以经典的 KSW 熵算法为例介绍其原理和计算过程。

KSW熵算法

设分割阈值为设分割阈值为t,

  

T为{0,1,2,...t}的灰度分布,B为{t+1,t+2,...L-1}的灰度分布,则概率分布为:

                                                                                                                         


式中

       

则这两个概率密度相关的熵为:

  

 

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

 

求出φ(t)最大时的灰度级t即为所求的最佳阈值。


最大熵阈值分割代码实现:

#include<opencv2\opencv.hpp>#include<cmath>#include<iostream>using namespace cv;using namespace std;double caculateCurrentEntropy(Mat &srcImage, int threshold){int nRows = srcImage.rows;int nCols = srcImage.cols;double BackgroundSum = 0, targetSum = 0;int nSumPix[256];double nProDis[256];double nSumProDis[256];double BackgroundEntropy = 0.0, targetEntropy = 0.0;    //首先初始化nSumPix[256]   nProDis[256]for (int i = 0; i < 256; i++){nSumPix[i] = 0;nProDis[i] = 0.0;nSumProDis[i] = 0.0;}for (int i = 0; i < nRows; i++){for (int j = 0; j < nCols; j++){nSumPix[(int)srcImage.at<uchar>(i, j)]++;}}for (int i = 0; i < 256; i++){nProDis[i] = (double)nSumPix[i] / (nRows*nCols);}nSumProDis[0] = nProDis[0];for (int i = 1; i < 256; i++){nSumProDis[i] = nSumProDis[i - 1] + nProDis[i];}BackgroundSum = nSumProDis[threshold];targetSum = 1 - BackgroundSum;for (int i = 0; i < 256; i++){if (i <= threshold){if (nProDis[i] == 0)continue;double ratio1 = nProDis[i] / BackgroundSum;BackgroundEntropy += -ratio1*logf(ratio1);}else{if (nProDis[i] == 0)continue;double ratio2 = nProDis[i] / targetSum;targetEntropy += -ratio2*logf(ratio2);}}return (BackgroundEntropy + targetEntropy);}int maxEntropy(Mat &srcImage){double maxentropy = 0;int max_index = 0;for (int i = 0; i < 256; i++){double cur_entropy = caculateCurrentEntropy(srcImage, i);if (cur_entropy > maxentropy){maxentropy = cur_entropy;max_index = i;}}return max_index;}int main(){Mat srcImage = imread("hand1.jpg");if (!srcImage.data){printf("could not load image...\n");return -1;}Mat srcGray;cvtColor(srcImage, srcGray, CV_BGR2GRAY);imshow("srcGray", srcGray);//caculateCurrentEntropy(srcGray, 100);int maxEntropyThreshold = maxEntropy(srcGray);cout << maxEntropyThreshold << endl;Mat maxEntropyResultImage = Mat::zeros(srcGray.rows, srcGray.cols, CV_8UC1);//创建一张一个通道的空的图像//利用得到的阈值进行二值操作for (int i = 0; i < srcGray.rows; i++){for (int j = 0; j < srcGray.cols; j++){if (srcGray.at<uchar>(i, j) > maxEntropyThreshold){maxEntropyResultImage.at<uchar>(i, j) = 255;}else{maxEntropyResultImage.at<uchar>(i, j) = 0;}}}imshow("maxEntropyResultImage", maxEntropyResultImage);waitKey(0);return 0;}
原图的灰度图:



最大熵阈值分割效果图:


阅读全文
0 0
原创粉丝点击