美文网首页
图像均衡化及直方图匹配的详细实现,python

图像均衡化及直方图匹配的详细实现,python

作者: 石小鑫 | 来源:发表于2018-11-25 16:19 被阅读0次

最近在学习图像处理方面的基础知识,在这里简单总结和分享。

一.直方图均衡化

图像的灰度直方图是一种概率直方图,表示不同灰度值在图像中出现的概率
图像的灰度直方图可以用来判断图像曝光是否合适,一种对曝光度异常的图像进行图像增强的操作就是直方图均衡化。
那么怎样进行图像直方图均衡化呢?

主流的图像处理库都封装了直方图均衡化的函数,比如matlab中的histeq()函数,对于这一函数的讲解可参考这篇文章histeq从用法到原理。
这里介绍一下如何自己写代码实现这一功能,使用了python语言。

将读取文件的灰度矩阵,转化为直方图,这里的直方图定义为python的dict类型,索引为灰度级,值为对应的概率。

#将灰度数组映射为直方图字典,nums表示灰度的数量级
def arrayToHist(grayArray,nums):
    if(len(grayArray.shape) != 2):
        print("length error")
        return None
    w,h = grayArray.shape
    hist = {}
    for k in range(nums):
        hist[k] = 0
    for i in range(w):
        for j in range(h):
            if(hist.get(grayArray[i][j]) is None):
                hist[grayArray[i][j]] = 0
            hist[grayArray[i][j]] += 1
    #normalize
    n = w*h
    for key in hist.keys():
        hist[key] = float(hist[key])/n
    return hist

直方图均衡化函数,传入原始图片的灰度矩阵和其直方图,计算累计的概率直方图,再进行均衡化。

#计算累计直方图计算出新的均衡化的图片,nums为灰度数,256
def equalization(grayArray,h_s,nums):
    #计算累计直方图
    tmp = 0.0
    h_acc = h_s.copy()
    for i in range(256):
        tmp += h_s[i]
        h_acc[i] = tmp

    if(len(grayArray.shape) != 2):
        print("length error")
        return None
    w,h = grayArray.shape
    des = np.zeros((w,h),dtype = np.uint8)
    for i in range(w):
        for j in range(h):
            des[i][j] = int((nums - 1)* h_acc[grayArray[i][j] ] +0.5)
    return des

绘制直方图的函数,借助pyplot

#传入的直方图要求是个字典,每个灰度对应着概率
def drawHist(hist,name):
    keys = hist.keys()
    values = hist.values()
    x_size = len(hist)-1#x轴长度,也就是灰度级别
    axis_params = []
    axis_params.append(0)
    axis_params.append(x_size)

    #plt.figure()
    if name != None:
        plt.title(name)
    plt.bar(tuple(keys),tuple(values))#绘制直方图
    #plt.show()

整个调用流程如下:

import numpy as np 
from matplotlib import pyplot as plt
from PIL import Image
import matplotlib

matplotlib.rcParams['font.sans-serif']=['SimHei']   # 用黑体显示中文

imdir = "./hw1_s.jpg"#原始图片的路径

#打开文件并灰度化
im_s = Image.open(imdir).convert("L")
im_s = np.array(im_s)
print(np.shape(im_s))

#开始绘图,分成四个部分
plt.figure()
plt.subplot(2,2,1)
plt.imshow(im_s,cmap = 'gray')
plt.title("原始灰度图")
#plt.show()

#创建原始直方图
plt.subplot(2,2,3)
hist_s = arrayToHist(im_s,256)
drawHist(hist_s,"原始直方图")

#计算均衡化的新的图片,根据累计直方图
im_d = equalization(im_s,hist_s,256)
plt.subplot(2,2,2)
plt.imshow(im_d,cmap="gray")
plt.title("均衡的灰度图")

#根据新的图片的数组,计算新的直方图
plt.subplot(2,2,4)
hist_d = arrayToHist(im_d,256)
drawHist(hist_d,"均衡直方图")

plt.show()

最终结果

equal.PNG

二.直方图匹配

直方图匹配类似于直方图均衡,不同之处在于直方图均衡的输出结果是固定的,较均衡的图像,而直方图匹配的结果则是我们指定的直方图,具体的数学原理不再赘述,不过注意,由于原始图像的累计直方图和我们指定的输出图片的直方图的累计直方图不可能完全相同,所以匹配结果并非百分之百的匹配
下面看实现
定义的匹配函数:注意第二个参数是我们指定的直方图,而非原始图片的直方图。

#直方图匹配函数,接受原始图像和目标灰度直方图
def histMatch(grayArray,h_d):
    #计算累计直方图
    tmp = 0.0
    h_acc = h_d.copy()
    for i in range(256):
        tmp += h_d[i]
        h_acc[i] = tmp

    h1 = arrayToHist(grayArray,256)
    tmp = 0.0
    h1_acc = h1.copy()
    for i in range(256):
        tmp += h1[i]
        h1_acc[i] = tmp
    #计算映射
    M = np.zeros(256)
    for i in range(256):
        idx = 0
        minv = 1
        for j in h_acc:
            if (np.fabs(h_acc[j] - h1_acc[i]) < minv):
                minv = np.fabs(h_acc[j] - h1_acc[i])
                idx = int(j)
        M[i] = idx
    des = M[grayArray]
    return des

具体调用,读取第二张图片,其直方图为我们指定的直方图

imdir = "./hw1_s2.jpg"
imdir_match = "./hw1_s22.jpg"

#直方图匹配
#打开文件并灰度化
im_s = Image.open(imdir).convert("L")
im_s = np.array(im_s)
print(np.shape(im_s))
#打开文件并灰度化
im_match = Image.open(imdir_match).convert("L")
im_match = np.array(im_match)
print(np.shape(im_match))
#开始绘图
plt.figure()

#原始图和直方图
plt.subplot(2,3,1)
plt.title("原始图片")
plt.imshow(im_s,cmap='gray')

plt.subplot(2,3,4)
hist_s = arrayToHist(im_s,256)
drawHist(hist_s,"原始直方图")

#match图和其直方图
plt.subplot(2,3,2)
plt.title("match图片")
plt.imshow(im_match,cmap='gray')

plt.subplot(2,3,5)
hist_m = arrayToHist(im_match,256)
drawHist(hist_m,"match直方图")

#match后的图片及其直方图
im_d = histMatch(im_s,hist_m)#将目标图的直方图用于给原图做均衡,也就实现了match
plt.subplot(2,3,3)
plt.title("match后的图片")
plt.imshow(im_d,cmap='gray')

plt.subplot(2,3,6)
hist_d = arrayToHist(im_d,256)
drawHist(hist_d,"match后的直方图")

plt.show()

最后结果

match.PNG
可以看到匹配出的图像与指定的图像灰度接近,灰度直方图相似。

相关文章

  • 图像均衡化及直方图匹配的详细实现,python

    最近在学习图像处理方面的基础知识,在这里简单总结和分享。 一.直方图均衡化 图像的灰度直方图是一种概率直方图,表示...

  • Metal图像处理——直方图均衡化

    Metal图像处理——直方图均衡化 Metal图像处理——直方图均衡化

  • 直方图匹配

    之前我们介绍过直方图均衡化。直方图匹配的核心思想就是在应用直方图的均衡化。 和之前直方图均衡化一样,直方图的匹配本...

  • 直方图均衡化—理论篇

    直方图均衡化--理论篇 直方图均衡化是数字图像处理中,最基本的一种处理。直方图均衡计算简单,并且适合快速的硬件实现...

  • 10、直方图应用

    直方图均衡化,实际上是调整图像的对比度,是图像增强的一种手段 (注:直方图均衡化都是基于灰度图像) 全局均衡化 局...

  • 直方图均衡化

    直方图均衡化的介绍 直方图均衡化是一种简单有效的图像增强技术,通过改变图像的直方图来改变图像中各像素的灰度,主要用...

  • exp1-空间域图像增强

    图像灰度变换 计算显示图像直方图、直方图均衡化 空间域图像平滑、锐化

  • python-opencv图像增强

    直方图均衡化 直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶上的分布更加均衡,提高了图像的对比度,达到...

  • 2019-04-10 OpenCV学习

    11边缘保留滤波(EPF) 美化图片 12图像直方图 13直方图应用 直方图均衡化:图像增强的一个手段 直方图比较...

  • 直方图均衡化

    直方图均衡化Histogram Equalization 理论Theory 图像的直方图是什么What is an...

网友评论

      本文标题:图像均衡化及直方图匹配的详细实现,python

      本文链接:https://www.haomeiwen.com/subject/zempqqtx.html