全局阈值处理 ostu算法

otsu算法
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
下面是我写的代码,也会参照别人写的

/**
* @brief       :直方图 统计各个灰度级的数量
* @param [in]  : src_image 源图像
*                height    高
*                width     宽
* @param [out] : histogram 各个灰度级统计结果
* @retval      :none
*/
void MyAlgorithm::Cal_Histogram(unsigned char *src_image, int height, int width, int *histogram)
{
	unsigned char *psrc_image = src_image;
	int *phistogram = histogram;
	int img_height = height;
	int img_width  = width;
	int i = 0;
	
	for (i = 0; i < (img_height*img_width); i++)
	{
		phistogram[psrc_image[i]]++;
	}
}

/**
* @brief       :计算各个灰度级的概率
* @param [in]  : histogram 
*                height    高
*                width     宽
* @param [out] : hist_prob 各个灰度级概率
* @retval      :none
*/
void MyAlgorithm::Cal_Hist_Prob(int *histogram, int height, int width,double *hist_prob)
{
	int *phistogram = histogram;
	double *phist_prob = hist_prob;
	int img_height = height;
	int img_width = width;
	int i = 0;

	for (i = 0; i < 256; i++)
	{
		hist_prob[i] = (double)histogram[i] / (double)(img_height * img_width);
	}
}

/**
* @brief       :计算各个灰度级的概率累加和
* @param [in]  : hist_prob 灰度级概率
* @param [out] : none
* @retval      :灰度级概率累加值
*/
double MyAlgorithm::Cal_Hist_Prob_Sum(double *hist_prob, int num)
{
	int i = 0;
	double sum = 0.0f;
	double *phist_prob = hist_prob;

	for (i = 0; i < num; i++)
	{
		sum += phist_prob[i];
	}
	return sum;
}

/**
* @brief       :计算灰度级累加均值
* @param [in]  : hist_prob 灰度级概率
* @param [out] : hist_prob 各个灰度级概率
* @retval      :none
*/
double MyAlgorithm::Cal_Ave_Sum(double *hist_prob, int num)
{
	double *phist_prob = hist_prob;
	double sum = 0.0f;
	int i = 0;

	for (i = 0; i < num; i++)
	{
		sum += i*phist_prob[i];
	}
	return sum;
}

/**
* @brief       :计算类间方差
*                ((mg * p1(k) - m1(k))*(mg * p1(k) - m1(k)))/(p1(k)(1-p1(k)))
* @param [in]  : hist_prob 灰度级概率
* @param [out] : none
* @retval      :灰度级概率累加值
*/
double MyAlgorithm::Cal_Sigma(double *hist_prob, double mg, int num)
{
	double p1 = 0.0;
	double m1 = 0.0;
	double sigma = 0.0;

	p1 = Cal_Hist_Prob_Sum(hist_prob, num);

	m1 = Cal_Ave_Sum(hist_prob,num);

	if ((fabs(p1) < 1e-15) || (fabs(1 - p1) < 1e-15))
		return 0.0;
	else
	{
		sigma = pow(mg*p1-m1,2)/(p1*(1-p1));
		return sigma;
	}
}

/**
* @brief       :otsu阈值处理
* @param [in]  : src_image 源图像
*                height    高
*                width     宽
* @param [out] : dst_iamge 目标图像
* @retval      :none
*/
void MyAlgorithm::Get_Otsu(unsigned char *src_image, unsigned char *dst_iamge, int height, int width)
{
	int i, j;

	unsigned char *psrc_image = src_image;
	unsigned char *pdst_image = dst_iamge;
	int img_height = height;
	int img_width = width;
	int index = 0;

	int histogram[256] = {0};                  //统计各个灰度级数量数组
	double hist_prob[256] = {0.0};            //各个灰度级概率数组
	double hist_prob_sum[256] = {0.0};        //灰度级累加和概率
	double ave_sum[256] = {0.0};              //累加均值

	double sigma[256] = { 0.0 };
	double mg = 0.0;
	double max_sigma = 0.0;
	int max_sigma_count = 0;

	int max_simga_ave = 0;
	int temp = 0;

	Cal_Histogram(psrc_image, img_height, img_width, histogram);
	Cal_Hist_Prob(histogram, img_height, img_width, hist_prob);
	mg = Cal_Ave_Sum(hist_prob,256);

	for (i = 0; i < 256; i++)
		sigma[i] = Cal_Sigma(hist_prob, mg, i);

	max_sigma = sigma[0];

	for (i = 1; i < 256; i++)
	{
		if (fabs(max_sigma - sigma[i]) < 1e-15)
		{
			temp += i;
			max_sigma_count++;
		}
		else if (sigma[i] > max_sigma)
		{
			max_sigma = sigma[i];
			max_sigma_count = 1;
			temp = i;
		}
	}
	max_simga_ave = temp / max_sigma_count;

	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			index = i * width + j;
			if (psrc_image[index] > max_simga_ave)
				pdst_image[index] = 0xff;
			else 
				pdst_image[index] = 0;
		}
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值