Python数字图像处理1.3

您所在的位置:网站首页 图像均衡化处理后数据量变小 Python数字图像处理1.3

Python数字图像处理1.3

2024-07-15 13:33| 来源: 网络整理| 查看: 265

本篇介绍数字图像处理中的图像直方图,读完本文,您将彻底理解直方图概念,并会使用Python语言来绘制一张图像的灰度直方图和彩色直方图。

[定义与算法] [直方图定义]

        直方图包括灰度直方图和彩色直方图两类,如果把灰度直方图看作是灰度通道的直方图,那么,彩色直方图可以看作是R/G/B三通道的独立直方图。

        灰度直方图描述的是图像中该灰度级对应的像素个数,也就是像素的统计信息。所谓的灰度级,就是像素的取值范围,通常为0-255,共256个值,因此对应256个灰度级。

        我们如何绘制直方图呢?如果我们以横坐标表示灰度级,纵坐标表示该灰度级像素的个数,以下图Fig.1所示测试图为例来做说明。

                                                                                           Fig.1 直方图示意图

        图中左边Test为一张宽高4×4大小的灰度图,不过我们使用了彩色来区分不同的灰度值。我们以横坐标表示灰度级,纵坐标表示像素个数,用对应颜色来区分不同灰度级,在Test中,我们统计不同灰度级对应的像素个数,如下所示:

        灰度级为2的像素有3个;

        灰度级为3的像素有1个;

        灰度级为4的像素有1个;

        灰度级为5的像素有4个;

        灰度级为6的像素有1个;

        灰度级为8 的像素有4个;

        灰度级为9的像素有2个;

        我们在右边坐标系中,用对应的颜色进行填充,每个小方格表示一个像素个数,这样就得到了一张高低不同的统计图,这种统计图就叫做直方图,从直方图中,我们可以很明了的看出,一张图中有多少个像素灰度级,每个灰度级有多少像素,进而可以根据直方图计算出对应的均值和方差等信息。

        直方图可以反应一张图的像素灰度级分布情况,但是无法反应图像的内容,一张直方图可能对应一张原始图像,也可能对应多张原始图像,图像内容不同,但像素对应灰度级分布相同。我们以图Fig.2为例,左右两张图,图A和图B内容是不一样的,但是,他们的灰度直方图分布却是一摸一样,正是因为他们每个灰度级像素数目是一样的。

        

                                                  (a)灰度图A                                      (b)灰度图B

                                                                        Fig.2 灰度直方图特例举例

[直方图特点]

         直方图具有平移、旋转和缩放不变性的特点。对于平移图像,旋转图像角度的情况下,图像操作前后的直方图分布不变,对于缩放图像,前后直方图的分布也基本不变,如图Fig.3所示。

              (a)原图直方图                         (b)平移图像直方图               (c)旋转图像直方图                   (d)放大图像直方图

                                                                       Fig.3 直方图平移旋转缩放不变性示意图

        正是由于直方图这些特性,使得直方图在图像分割、图像分类和图像检索以及图像识别中意义重大。

[绘制与代码]

[直方图绘制]

        了解了直方图的定义,我们就可以用简单的Python语言来绘制出图像的直方图。

        在matplotlib中有一个接口hist,定义如下:

matplotlib.pyplot.hist( x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype=u'bar', align=u'mid', orientation=u'vertical', rwidth=None, log=False, color=None, label=None, stacked=False, hold=None, **kwargs)

        这个接口参数说明如下:

 

实际上在使用中,我们只需要记住前面三个参数就可以了:

①x表示的是直方图的数据,也就是图像的数组,不过这里要注意,这个数组x表示的是一维数组;

②bins表示条形数,一般对于图像直方图,我们选择256;

③color表示颜色,也就是绘制直方图的颜色,如"r","g","b","gray"等;

按照上面的介绍,我们要绘制直方图,首先要获取图像的一维数据,也就是读取一副彩色图像之后,获取彩色图像的r,g,b和灰度的一维像素数组,我们给出代码如下:

def imgHist(im): color_rgb = np.array(im)#dtype=np.int32 rows = im.shape[0] cols = im.shape[1] gray = np.zeros((rows, cols)) r = np.zeros((rows, cols)) g = np.zeros((rows, cols)) b = np.zeros((rows, cols)) for i in range (rows): for j in range (cols): gray[i,j] = np.clip((color_rgb[i, j, 0] + color_rgb[i, j, 1] + color_rgb[i, j, 2]) * 0.3333 * 255.0,0.0,255.0) r[i,j] = color_rgb[i, j, 0] g[i,j] = color_rgb[i, j, 1] b[i,j] = color_rgb[i, j, 2] return gray, r, g, b

有了上述内容,我们直方图绘制的完整代码如下:

import numpy as np import matplotlib.pyplot as plt import matplotlib.image as img ##获取二维图像的各个分量一维数组,包括分两red,green,blue,gray def imgHist(im): color_rgb = np.array(im) rows = im.shape[0] cols = im.shape[1] gray = np.zeros((rows, cols)) r = np.zeros((rows, cols)) g = np.zeros((rows, cols)) b = np.zeros((rows, cols)) for i in range (rows): for j in range (cols): gray[i,j] = np.clip((color_rgb[i, j, 0] + color_rgb[i, j, 1] + color_rgb[i, j, 2]) * 0.3333 * 255.0,0.0,255.0)#这里使用的是明度公式获取gray分量 r[i,j] = color_rgb[i, j, 0] g[i,j] = color_rgb[i, j, 1] b[i,j] = color_rgb[i, j, 2] return gray, r, g, b im = img.imread("test.png") #图像读取 gray, r, g, b = imgHist(im) #获取图像分量数据 gray = gray.reshape(-1) #将灰度数据转换为一维数组 plt.hist(gray, bins = 128, color="gray")#绘制gray分量直方图 plt.show() #显示直方图 r = r.reshape(-1) #将red分量数据转换为一维数组 plt.hist(r, bins = 128, color="r") #绘制red分量直方图 plt.show() #显示直方图 g = g.reshape(-1) #将green分量数据转换为一维数组 plt.hist(g, bins = 128, color="g") #绘制green分量直方图 plt.show() #显示直方图 b = b.reshape(-1) #将blue分量数据转换为一维数组 plt.hist(b, bins = 128, color="b") #绘制blue分量直方图 plt.show() #显示直方图

效果图如下:

                   (a)gray分量直方图                           (b)red分量直方图                             (c)green分量直方图                          (d)blue分量直方图

                                                                                                     Fig.4直方图绘制结果图

[知识扩展]         直方图在图像处理中具有很重要的作用,在图像分类,分割等多方面应用广泛,本文只是做了最简单的介绍,为初学者必修内容,对于直方图扩展部分,可以了解直方图匹配,直方图均衡化以及基于直方图的各种图像增强等部分内容。

        直方图还有一个需要大家注意的地方,对于PHOTOSHOP很熟悉的人也会经常用到,我们可以通过直方图来判断一张图像是否偏暗、偏亮或者光线正常,如下图Fig.5所示,我们将直方图按照灰度级进行区域划分,分为阴影-暗部、中间调、和高光-亮部三个区域,哪个区域的像素统计数量较多,也就是图中黑色面积较多,那么,图像就偏向那个区域。

                  Fig.5 直方图判断示意图

        以图Fig.6为例,图(a)阴影区域过大,那么,图像整体就偏暗,图(c)高光区域偏大,那么图像就偏亮或者过曝。通过这些判断,我们就可以对不同的图做出不同的亮度对比度调节,来修正图像,还原完美的照片!

                     (a)                                        (b)                                           (c)

                                                   Fig.6 直方图判断举例图

最后,希望大家努力学习,共勉!

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3