您的位置:首页 > 编程语言 > C语言/C++

基于OpenCV和C++实现最大阈值分割算法

2017-02-24 17:55 471 查看
代码如下::

/**********************************************************************************************************
*文件说明:
* 基于OpenCv的阈值分割算法
*开发环境:
* win7+vs2010+opencv2.4.8
*时间地点:
* 陕西师范大学.2017.2。19
*作 者:
* 李丽
***********************************************************************************************************/
#include<opencv2/opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
using namespace cv;

/***********************************************************************************************************
宏定义
***********************************************************************************************************/
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 i,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); //cvQueryHistValue_1D()函数是访问直方图的方式
}
double cur_entropy = 0.0;
for(i = start; i < end; i++)
{
if((int)cvQueryHistValue_1D(Histogram1,i) == 0)
continue;
float percentage = cvQueryHistValue_1D(Histogram1, i) / total;
cur_entropy += - percentage * logf(percentage); // 能量的定义公式
}
return cur_entropy;
}

/***********************************************************************************************************
// 寻找最大熵阈值并分割
***********************************************************************************************************/

void MaxEntropy(IplImage *src, IplImage *dst)
{

CvHistogram * hist = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, HistogramRange); //OpenCV中直方图的 CvHistogram数据类型的理解

cvCalcHist(&src, hist); //创建直方图
double maxentropy = -1.0; ////???
int max_index = -1; ////???
// 循环测试每个分割点,寻找到最大的阈值分割点
for(int i = 0; i < HistogramBins; i++) // int HistogramBins = 256;
{
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()
{
IplImage* src = cvLoadImage("G:\\C++Study\\Demo\\MaxETG\\MaxETG\\lena.png",CV_LOAD_IMAGE_GRAYSCALE ); //CV_LOAD_IMAGE_GRAYSCALE
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;
}

运行结果如下:  左边为原始图像   右边为最大熵阈值分割函数处理之后的函数

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: