OpenCV编程案例:最大熵阈值分割算法实现
http://www.aiseminar.cn/?action-viewthread-tid-700
下面程序使用OpenCV的相关函数,实现了最大熵阈值分割算法。作者为crond123,本人在自己的运行过程中,根据错误提示进行相应修改,并在下面图像上运行试验。
程序maxentropythreshold.cpp源码如下:
CODE:
/*==================================================================
运行中使用图像如下:
= 代码内容:最大熵阈值分割
= 修改日期:2009-3-3
= 作者:crond123
= 博客:http://blog.csdn.net/crond123/
= E_Mail:crond123@163.com
= 修改:jink2005
= 论坛:http://www.aiseminar.cn/bbs
====================================================================*/
#include "cv.h"
#include "highgui.h"
#include <iostream>
#pragma comment(lib, "highgui.lib")
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cvaux.lib")
#pragma comment(lib, "cxcore.lib")
int HistogramBins = 256;
float HistogramRange1[2] = {0,255};
float *HistogramRange[1] = {&HistogramRange1[0]};
typedef enum {back,object} entropy_state;
// 计算当前位置的能量熵
double caculateCurrentEntropy(CvHistogram * Histogram1, int cur_threshold, entropy_state state)
{
int start,end;
if(state == back)
{
start = 0;
end = cur_threshold;
}
else
{
start = cur_threshold;
end = 256;
}
int total = 0;
for(int i = start; i < end; i++)
{
total += (int)cvQueryHistValue_1D(Histogram1, i);
}
double cur_entropy = 0.0;
for(i = start; i < end; i++)
{
if((int)cvQueryHistValue_1D(Histogram1,i) == 0)
continue;
double percentage = cvQueryHistValue_1D(Histogram1, i) / total;
cur_entropy += - percentage * logf(percentage); // 能量的定义公式
}
return cur_entropy;
}
// 寻找最大熵阈值并分割
void MaxEntropy(IplImage *src, IplImage *dst)
{
assert(src != NULL);
assert(src->depth == 8 && dst->depth == 8);
assert(src->nChannels == 1);
CvHistogram * hist = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, HistogramRange);
cvCalcHist(&src, hist);
double maxentropy = -1.0;
int max_index = -1;
// 循环测试每个分割点,寻找到最大的阈值分割点
for(int i = 0; i < HistogramBins; i++)
{
double cur_entropy = caculateCurrentEntropy(hist, i, object) + caculateCurrentEntropy(hist, i, back);
if(cur_entropy > maxentropy)
{
maxentropy = cur_entropy;
max_index = i;
}
}
cvThreshold(src, dst, (double)max_index, 255, CV_THRESH_BINARY);
cvReleaseHist(&hist);
}
int main(int argc, char* argv[])
{
IplImage* src; //声明IplImage指针
// 载入图像
if( argc == 2 && (src = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE)) != 0 )
;
else // 如果无参数,载入工作目录下文件名为apple.jpg的图片。
{
src = cvLoadImage("apple.jpg", CV_LOAD_IMAGE_GRAYSCALE);
}
if(src == NULL)
{
std::cout << "Can't find the image file!" << std::endl;
return -1;
}
cvNamedWindow("Image", 1); // 创建窗口
cvNamedWindow("origin", 1);
IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
MaxEntropy(src, dst);
cvShowImage("Image", dst); // 显示图像
cvShowImage("origin", src);
cvWaitKey(0); // 等待按键
cvDestroyWindow("Image"); // 销毁窗口
cvDestroyWindow("origin");
cvReleaseImage(&src); // 释放图像
cvReleaseImage(&dst);
return 0;
}
结果为:
参考文献:
[1] crond123. 最大熵阈值分割算法的C语言实现[EB/OL]. http://blog.csdn.net/crond123/archive/2009/03/03/3952597.aspx, 2009-03-03/2009-11-19