您的位置:首页 > 理论基础

CV学习-直方图均衡化

2017-03-21 16:46 120 查看

利用直方图均衡化增强图像

利用直方图均衡化增强图像
概述

灰度直方图

核心思想

证明过程

代码

测试结果

概述

图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法。直方图拉伸和直方图均衡化是两种最常见的间接对比度增强方法。直方图拉伸是通过对比度拉伸对直方图进行调整,从而“扩大”前景和背景灰度的差别,以达到增强对比度的目的,这种方法可以利用线性或非线性的方法来实现;直方图均衡化则通过使用累积函数对灰度值进行“调整”以实现对比度的增强。

直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。这种方法通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。

灰度直方图

概念

灰度直方图(histogram)是灰度级的函数,它表示图象中具有每种灰度级的象素的个数,反映图象中每种灰度出现的频率。灰度直方图的横坐标是灰度级,纵坐标是该灰度级出现的频率,是图象的最基本的统计特征。

从概率的观点来理解,灰度出现的频率可看作其出现的概率,这样直方图就对应于概率密度函数pdf,而概率分布函数就是直方图的累积和,即概率密度函数的积分.

性质

它只反映该图像中不同灰度值出现的次数,而未反映某一灰度值像素所在的位置。也就是说,它只包含了该图像中某一灰度值的像素出现的概率,而丢失了其所在位置的信息。

核心思想

直方图均衡化处理的中心思想是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。

对图像空间域点的增强过程是通过增强函数t=EH(s)来完成的,t、s分别为目标图像和原始图像上的像素点(x, y)处的灰度值。

在进行均衡化处理时,增强函数EH需要满足两个条件:

1)、增强函数EH(s)在0≤s≤L-1的范围内是一个单调递增函数,这个条件保证了在增强处理时没有打乱原始图像的灰度排列次序;

2)、对于0≤s≤L−1应当有0≤EH(s)≤L−1,它保证了变换过程中灰度值的动态范围的一致性。同样的,对于反变换过程s=EH-(t),在0≤t≤1时也必须满足上述两个条件。

可以证明累积分布函数就是满足上述条件,通过该函数可以完成s到t的均匀分布转换,即使直方图均衡化的灰度变化函数是累积分布函数(概率分部函数)。

离散情况下的增强转换方程为:



彩色图片可以分别提取RGB三个通道的值分别进行直方图均衡化操作,然后再将三个通道的值合并成彩色图像。

证明过程





代码

实现代码采用CImg.h读入和显示图像,CImg 库是一个免费、开源的图像处理C++库,名称原意是 Cool Image,正如其名,CImg是一个非常优秀、功能强大、代码简洁、使用方便的C++ 图像处理库。

代码可以到CImg官网下载

CImg 官网:http://cimg.sourceforge.net/

main.cpp

#include "CImg.h"
#include <string>
#include <iostream>

using namespace cimg_library;
using namespace std;

void ImgHE(const char* filename, bool isGray) {
// 读入图片
CImg<unsigned char> source;
source.load_bmp(filename);

// 测试用例预处理
CImg<unsigned char> img;
if (source.spectrum() == 3 && isGray) {
img = source.get_RGBtoGray();
}
else if (source.spectrum() == 1 && !isGray) { // 灰度图片作彩色图片处理
cout << "error test!" << endl;
return;
}
else {
img = source;
}

// 图片参数
int height = img.height();
int width = img.width();
int size = width * height;
int channel = img.spectrum();

// 结果图像
CImg<unsigned char> result(width, height, 1, channel, 0);

// RGB三个通道分别进行直方图均衡化
// 灰度图片只有一个通道
for (int k = 0; k < channel; k++) {
int hg[256] = { 0 }; // 直方图
float hgPDF[256] = { 0 };  // PDF
float hgCDF[256] = { 0 };  // CDF
int hgEQL[256] = { 0 };  //归一化直方图

// 统计像素值分布直方图
cimg_forXY(img, x, y) {
hg[(int)img(x, y, 0, k)]++;
}

for (int i = 0; i < 256; i++) {
hgPDF[i] = (float)hg[i] / size;  // PDF

if (i == 0) {                    // CDF
hgCDF[i] = hgPDF[i];
}
else hgCDF[i] = hgCDF[i - 1] + hgPDF[i];

hgEQL[i] = (int)(255 * hgCDF[i] + 0.5);  // 归一化 t = int[(L-1)*s + 0.5]
}

// 生成结果图像
cimg_forXY(img, x, y) {
result(x, y, 0, k) = hgEQL[(int)img(x, y, 0, k)];
}
}

// 显示结果
(img, result).display();
}

int main() {

// HistogramEqualization
ImgHE("1.bmp", true);
ImgHe("1.bmp", false);

return 0;
}


测试结果

左图为原图,右图为增强后的图



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