版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/love_image_xie/article/details/87943245
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//计算给定阈值下的熵
float calCurrentEntropy(Mat& hist, int threshold)
{
float backgroundSum = 0, targetSum = 0;
const float* pDataHist = (float*)hist.ptr<float>(0);
for (int i = 0; i < 256; i++)
{
if (i < threshold)
{
backgroundSum += pDataHist[i];
}
else
targetSum += pDataHist[i];
}
float backgroundEntropy = 0, targetEntropy = 0;
for (int i = 0; i < 256; i++)
{
if (i < threshold)
{
if (pDataHist[i] == 0)
continue;
float ratio1 = pDataHist[i] / backgroundSum;
backgroundEntropy += -ratio1*logf(ratio1);
}
else
{
if (pDataHist[i] == 0)
continue;
float ratio2 = pDataHist[i] / targetSum;
targetEntropy += -ratio2*logf(ratio2);
}
}
return (targetEntropy+backgroundEntropy);
}
//计算最大熵
Mat maxEntropySegMentation(Mat& src)
{
const int channels[1] = {0};
const int histSize[1] = {256};
float pranges[2] = {0,256};
const float* ranges[1] = {pranges};
MatND hist;
calcHist(&src,1,channels,Mat(),hist,1,histSize,ranges);
float maxEntropy = 0;
int max_index = 0;
Mat result;
for (int i = 0; i < 256; i++)
{
//计算当前的熵
float cur_entropy = calCurrentEntropy(hist,i);
if (cur_entropy > maxEntropy)
{
maxEntropy = cur_entropy;
max_index = i;
}
}
//二值分割
threshold(src,result,max_index,255,CV_THRESH_BINARY);
return result;
}
int main()
{
Mat src = imread("E:\\研究生\\学习材料\\学习书籍\\OpenCV图像处理编程实例-源码-20160801\\《OpenCV图像处理编程实例-源码-20160801\\images\\flower3.jpg");
if (!src.data)
return -1;
Mat gray;
cvtColor(src,gray,CV_BGR2GRAY);
Mat result = maxEntropySegMentation(gray);
imshow("gray",gray);
imshow("result",result);
waitKey(0);
}
结果如下: