数字图像处理之直方图均衡化

以下例子源自《数字图像处理》第三版

r表示待处理图像的灰度,取值区间[0,L-1]。r=0表示黑色,r= L-1表示白色。输出灰度值s,变换形式:

s = T(r) ,0<=r<=L-1。

离散变换形式

sk = T(rk) = (L-1)(pr0+pr1+...+prk) ,pr为像素值的概率密度。

 (L-1)(n0+n1+...+nk)/MN,n为每个像素值对于的个数,M、N为图像行和列数。

笔者采用c++语言,编写了直方图均衡化处理的类,并用opencv绘制了均衡化前后的统计直方图,以及通过直方图均衡化的原图像。

类的头文件代码如下:

//<span style="font-family: Arial, Helvetica, sans-serif;">histogramEqualization.h</span>
#ifndef  _HIS_E_
#define _HIS_E_

class hisEqt
{
public:
	hisEqt::hisEqt();
	hisEqt::~hisEqt();
public:
	int w ;
	int h;
	int nlen;

	int *pHis;
	float *pdf;

	//=====求像素分布概率密度====
	void  getPdf();

	//======统计像素个数=======
	void getHis(unsigned char*imgdata);

	//==========画统计分布直方图===============
	//void drawHistogram(const float*pdf,Mat &hist1);

	//===========直方图均衡化==========
	void hisBal();

	//====直方图均衡化后的图像===
	void imgBal(unsigned char* img);
};




#endif
类源文件:

#include <iostream>
#include "histogramEqualization.h"

using namespace std;

hisEqt::hisEqt():nlen(0){
	pHis = new int[256*sizeof(int)];
	memset(pHis,0,256*sizeof(int));
	pdf = new float[255*sizeof(float)];
	memset(pdf,0,255*sizeof(float));
}

hisEqt::~hisEqt(){
	delete []pHis;
	delete []pdf;
}


//======统计像素个数=======
void hisEqt::getHis(unsigned char*imgdata){
	for (int i =0;i<nlen;i++)
	{
		pHis[imgdata[i]]++;
	}
}


//=====求像素分布概率密度====
void hisEqt:: getPdf(){
	for(int k =0;k<256;k++)
	{
		pdf[k] = pHis[k]/float(nlen);
	}
}

//===========直方图均衡化==========
void hisEqt::hisBal(){
	for(int k =1;k<256;k++)
	{
		pdf[k] += pdf[k-1];
	}
	for(int k =0;k<256;k++)
	{
		pHis[k] = 255*pdf[k];
	}
}

//====直方图均衡化
void hisEqt:: imgBal(unsigned char* img){
	for (int i =0;i<nlen;i++)
	{
		img[i] = pHis[img[i]];
	}
}

最后写了测试函数test.cpp,代码如下:

#include <opencv2/opencv.hpp>
#include "histogramEqualization.h"
using namespace cv;
void drawHistogram(const float*pdf,Mat& hist1);
int main()
{
	Mat image = imread("Fig0308(a)(pollen).tif");
	if (!image.data)
	{

		return -1;
	}


	Mat hist2(256,256,CV_8UC3,Scalar(0,0,0));
	Mat hist1(256,256,CV_8UC3,Scalar(0,0,0));

	Mat imgOut = Mat(image.rows,image.cols,CV_8UC3,Scalar(0,0,0));
	vector<Mat> planes;
	int chn = image.channels();
	if (chn==3)
	{
		split(image,planes);

	}
	while (chn)
	{
		chn--;
		unsigned char* imageData =  new unsigned char[sizeof(unsigned char)*(image.cols*image.rows)];
		memcpy(imageData,planes[chn].data,planes[chn].cols*planes[chn].rows);
		hisEqt his;
		his.nlen = image.rows*image.cols;
		his.getHis(imageData);
		his.getPdf();

		//	//======画原图直方图并保存============
		drawHistogram(his.pdf,hist1);
		imwrite("hisline.jpg",hist1);

		his.hisBal();
		his.getPdf();
		//	//======画均衡化后直方图并保存============
		drawHistogram(his.pdf,hist2);
		imwrite("his_balanceline.jpg",hist2);

		//	//=====图像均衡化===
		his.imgBal(imageData);
		memcpy(planes[chn].data,imageData,planes[chn].cols*planes[chn].rows);
		imageData = NULL;
		delete[] imageData;
	}

	//merge(planes0,imgOut);
	merge(planes,image);
	imwrite("result.jpg",image);
}

void drawHistogram(const float *pdf,Mat& hist1){
	for(int k =0;k<256;k++)
	{
		/*if (k>0)
		{
		Point a(k-1,255-pdf[k-1]*2550),b(k,255-pdf[k]*2550);
		line( hist1,
		a,
		b,
		Scalar( 0, 0, 255 ),
		2);
		}*/
		if (k%2==0)
		{
			Point a(k,255),b(k,255-pdf[k]*2550);
			line( hist1,
				a,
				b,
				Scalar( 0, 0, 255 ),
				1);
		}
		else
		{
			Point a(k,255),b(k,255-pdf[k]*2550);
			line( hist1,
				a,
				b,
				Scalar( 0, 255, 0 ),
				1);
		}


	}
}

结果如图:

原图直方图原图直方图

均衡化后直方图

原图像(出自冈萨雷斯第三版)

直方图均衡化后的图:






转载请注明出处:http://write.blog.csdn.net/postedit/46940805
实验代码下载:http://download.csdn.net/my



版权声明:本文为博主原创文章,未经博主允许不得转载。





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值