下面程序使用OpenCV的相关函数,实现了最大熵阈值分割算法。作者为,本人在自己的运行过程中,根据错误提示进行相应修改,并在下面图像上运行试验。
程序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;}
运行中使用图像如下: