数字图像基础(二)
上一篇文章我说了,数字图像的灰度化和二值化。现在呢,该说一说,数字图像处理中一个重要内容。
1.灰度直方图
灰度直方图(histogram)是灰度级的函数,它表示图象中具有每种灰度级的象素的个数,反映图象中每种灰度出现的频率。如下图所示,灰度直方图的横坐标是灰度级,纵坐标是该灰度级出现的频率,是图象的最基本的统计特征。
(图片来自于网络:https://wenwen.sogou.com/z/q190092407.htm)
换个角度认识图像(直方图)
第一个就是当我们面对图像的时候,我们面对的是抽象的矩阵,如下图,下面是0-255的灰度图像的表示,密密麻麻的
而我们的直方图呢,就是对这些灰度值的统计,绘制成直方图。
具体如何绘制直方图这里,我提供一段代码,仅供参考
<span style="font-size:18px;">#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void Help()
{
printf("\n\n\t\t\t欢迎来到直方图的世界!\n");
printf("\n\n ----------------------------------------------------------------------------\n");
}
int main()
{
Mat srcImage = imread("lena.jpg", 0);
imshow("原图",srcImage);
if(!srcImage.data) {cout << "fail to load image" << endl; return 0;}
system("color 1F");
Help();
MatND dstHist; // 在cv中用CvHistogram *hist = cvCreateHist
int dims = 1;
float hranges[2] = {0, 255};
const float *ranges[1] = {hranges}; // 这里需要为const类型
int size = 256;
int channels = 0;
//计算图像的直方图
calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges); // cv 中是cvCalcHist
int scale = 1;
Mat dstImage(size * scale, size, CV_8U, Scalar(0));
//获取最大值和最小值
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist,&minValue, &maxValue, 0, 0); // 在cv中用的是cvGetMinMaxHistValue
//绘制出直方图
int hpt = saturate_cast<int>(0.9 * size);
for(int i = 0; i < 256; i++)
{
float binValue = dstHist.at<float>(i); // 注意hist中是float类型
int realValue = saturate_cast<int>(binValue * hpt/maxValue);
//rectangle(dstImage,Point(i*scale, size - 1), Point((i+1)*scale - 1, size - realValue), Scalar(255));
line(dstImage,Point(i*scale,size-1),Point((i+1)*scale-1,size-realValue),Scalar(255));
}
imshow("一维直方图", dstImage);
waitKey(0);
return 0;
}</span
2.直方图均衡化
直方图均衡化(Histogram Equalization)是直方图最典型的应用,是图像点运算的一种。对于一幅输入图像,通过运算产生一幅输出图像,点运算是指输出图像的每个像素点的灰度值由输入像素点决定,即:
直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数过程。从分布图上的理解就是希望原始图像中y轴的值在新的分布中尽可能的展开。变换过程是利用累积分布函数对原始分布进行映射,生成新的均匀拉伸的分布。因此对应每个点的操作是寻找原始分布中y值在均匀分布中的位置,如下图是理想的单纯高斯分布映射的示意图:
(图片来源:《Learnning OpenCV》 p189)
这里我在更详细的介绍一下,直方图的均衡化的原理,以及是如何实现的。
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法.
说得更清楚一些, 以下面的直方图为例, 你可以看到像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围. 见下面左图: 绿圈圈出了 少有像素分布其上的 强度值. 对其应用均衡化后, 得到了中间图所示的直方图. 均衡化的图像见下面右图.
直方图均衡化实现
直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。
直方图均衡化的基本思想是把原始图的直方图变换为均匀分布的形式,这样就增加了象素灰度值的动态范围从而可达到增强图像整体对比度的效果。设原始图像在(x,y)处的灰度为f,而改变后的图像为g,则对图像增强的方法可表述为将在(x,y)处的灰度f映射为g。在灰度直方图均衡化处理中对图像的映射函数可定义为:g = EQ (f),这个映射函数EQ(f)必须满足两个条件(其中L为图像的灰度级数):
(1)EQ(f)在0≤f≤L-1范围内是一个单值单增函数。这是为了保证增强处理没有打乱原始图像的灰度排列次序,原图各灰度级在变换后仍保持从黑到白(或从白到黑)的排列。
(2)对于0≤f≤L-1有0≤g≤L-1,这个条件保证了变换前后灰度值动态范围的一致性。
下一篇: 数据结构与算法——栈与队列(二)