原理不多说
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
void Ksw1dSegmentation(unsigned char* image, int width, int height);//最大熵阈值分割算法
/*************************************************************************
** 函数名称:
** Ksw1dSegmentation()
** 参数
** unsigned char* image 指向图像的指针
** int width 图像的宽度
** int height 图像的高度
** 返回值:
** 无
** 说明:
** 针对高对比度、双峰分布的红外图像,利用最大熵原理自适应分割目标
************************************************************************/
void Ksw1dSegmentation(unsigned char* image, int width, int height)
{
//int lLBytes = LINEBYTES(width*8);
//1.计算直方图
/////////////////////////////////////////////////////////
int *histArray_1D = new int[256];
int i, x, y;
//直方图数组清0
for (i = 0; i<256; i++)
histArray_1D[i] = 0;
//中间变量
int temp;
//统计灰度直方图
for (y = 0; y<height; y++)
{
for (x = 0; x<width; x++)
{
int k = width*y + x;
temp = image[k];
histArray_1D[temp]++;
}
}
//2.计算最佳阈值
////////////////////////////////////////////////////////////
//熵及最大熵
float Entropy, maxEntropy = 0;
int MaxT = 0;
float Ht = 0.0, H1 = 0.0, p = 0.0, pt = 0.0;
float N = float(height*width);
for (i = 0; i<256; i++)
{
p = float(histArray_1D[i]) / N;
if (p<0.00000001)
continue;
H1 += -float(p*log10(p));
}
for (i = 0; i<256; i++)
{
p = float(histArray_1D[i]) / N;
pt += p;
if (p<0.00000001)
continue;
Ht += -float(p*log10(p));
Entropy = float(log10(pt*(1 - pt)) + Ht / pt + (H1 - Ht) / (1 - pt));
if (Entropy>maxEntropy)
{
maxEntropy = Entropy;
MaxT = i;
}
}
//3.图像二值化
///////////////////////////////////////////////////////////////////
for (y = 0; y<height; y++)
{
for (x = 0; x<width; x++)
{
int k = width*y + x;
if (image[k]>MaxT) //亮点为白色
{
image[k] = 255;
}
else
{
image[k] = 0;
}
}
}
delete[] histArray_1D;
}
int main()
{
//Mat lena=imread("1.tif");
Mat lena = imread("test2.png");
//Mat lena=imread("lena.jpg");
cvtColor(lena, lena, CV_RGB2GRAY);
int height = lena.rows;
int width = lena.cols;
uchar* covertimage = new uchar[height * width];
uchar* p;
int i, j;
for (i = 0; i<height; i++)
{
p = lena.ptr<uchar>(i);
for (j = 0; j<width; j++)
{
covertimage[i*width + j] = p[j];
}
}
Ksw1dSegmentation(covertimage, width, height);
Mat outimage(height, width, CV_8UC1, covertimage); //一维数组转Mat类
imshow("output", outimage);
waitKey(0);
delete[] covertimage;
return 0;
}