直方图均衡化

#include "cv.h"
#include"highgui.h"
using namespace cv;
using namespace std;

/*
直方图均衡化
基本思想:把原始图的直方图变换为均匀分布的形式,
这样就增加了像素灰度值的动态 范围,从而达到增强图像整体对比度的效果
*/
void HE(Mat img)
{
	int nub[256] = {0};
	double p[256] = {0.0};
	for(int i = 0 ; i < img.rows; ++i)
	{
		for(int j = 0 ; j < img.cols ; ++j)
		{
			nub[ img.at<uchar>(i,j) ]++;
		}
	}
	int sum = img.rows*img.cols;
	for(int i = 0 ; i < 256 ; ++i)
	{
		if( i == 0 )p[0] = 1.0*nub[i] / sum; 
		else p[i] = p[i-1] + 1.0*nub[i] / sum;
	}

	for(int i = 0 ; i < img.rows ; ++i)
	{
		for(int j = 0 ; j < img.cols ; ++j)
		{
			img.at<uchar>(i,j) = uchar(255*p[img.at<uchar>(i,j)]);
		}
	}
	imshow("HE",img);
}

/*  
自适应直方图均衡化
自适应直方图均衡化(AHE)用来提升图像的对比度的一种计算机图像处理技术。和普通的直方图均衡算法不同,AHE算法通过计算图像的局部直方图,然后重新分布亮度来来改变图像对比度。因此,该算法更适合于改进图像的局部对比度以及获得更多的图像细节。
*/
void AHE(Mat img , int step = 8)
{
	Mat res = img.clone();
	int w = img.cols;
	int h = img.rows;
	int step_wnub = w / step;
	int step_hnub = h / step;

	double p[8*8+1][256] = {0};
	int nub[8*8+1][256] = {0};

	int cnt = 0;
	int sum = step_wnub*step_hnub;
	for(int py = 0 ; py < step ; ++py)
	{
		for(int px = 0 ; px < step ; ++px)
		{
			for(int i = py*step_hnub; i < py*step_hnub+step_hnub ; ++i)
				for( int j = px*step_wnub; j < px*step_wnub+step_wnub ; ++j)
					nub[cnt][ img.at<uchar>(i,j) ]++;
		
			for(int i = 0 ; i < 256 ; ++i){
				if( i == 0 )p[cnt][0] = 1.0*nub[cnt][i] / sum; 
				else p[cnt][i] = p[cnt][i-1] + 1.0*nub[cnt][i] / sum;
			}

			for(int i = py*step_hnub; i < py*step_hnub+step_hnub ; ++i)
				for( int j = px*step_wnub; j < px*step_wnub+step_wnub ; ++j){
					//if( cnt == 0)cout << i << " " << j << " " << img.size()  << endl;
					img.at<uchar>(i,j) = uchar(255*p[cnt][img.at<uchar>(i,j)]);
					//cout << img.at<uchar>(i,j) << endl;
				}
					
			cnt++;
		}
	}
	imshow("AHE",img);
}

/*
限制对比度的直方图均衡化
*/

Mat CLHE(Mat img,int _step = 8)
{
    int width = img.cols;
    int height= img.rows;
    Mat CLHE_GO = img.clone();
    int tmp[256] ={0};
    float C[256] = {0.0};
    int total = width*height;  
    for (int i=0 ;i<img.rows;i++)
    {
        for (int j=0;j<img.cols;j++)
        {
            int index = img.at<uchar>(i,j);
            tmp[index] ++;
        }
    }
    /////////////////////////限制对比度计算部分,注意这个地方average的计算不一定科学
    int average = width * height / 255/64;  
    int LIMIT = 4 * average;  
    int steal = 0;  
    for(int k = 0 ; k < 256 ; k++)  
    {  
        if(tmp[k] > LIMIT){  
            steal += tmp[k] - LIMIT;  
            tmp[k] = LIMIT;  
        }  
    }  
    int bonus = steal/256;  
    //hand out the steals averagely  
    for(int k = 0 ; k < 256 ; k++)  
    {  
        tmp[k] += bonus;  
    }  
    ///////////////////////////////////////////
    //计算累积函数  
    for(int i = 0;i < 256 ; i++){  
        if(i == 0)  
            C[i] = 1.0f * tmp[i] / total;  
        else  
            C[i] = C[i-1] + 1.0f * tmp[i] / total;  
    }  
    //这里的累积函数分配的方法非常直观高效
    for(int i = 0;i < img.rows;i++){  
        for(int j = 0;j < img.cols;j++){      
            int index = img.at<uchar>(i,j);
            CLHE_GO.at<uchar>(i,j) = C[index] * 255  ;
        }  
    }  
    return CLHE_GO;
}
/*
   CLAHE同普通的自适应直方图均衡不同的地方主要是其对比度限幅。这个特性也可以应用到全局直方图均衡化中,即构成所谓的限制对比度直方图均衡(CLHE),但这在实际中很少使用。在CLAHE中,对于每个小区域都必须使用对比度限幅。CLAHE主要是用来克服AHE的过度放大噪音的问题。 */


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值