数字图像处理:直方图均衡推导及实现

推导

冈萨雷斯的书里给了几个公式,书中的式3.3-3一直不明白是如何得出的。
p s ( s ) d s = p r ( r ) d r p_s(s)ds=p_r(r)dr ps(s)ds=pr(r)dr

下面参考一些文章加上自己理解进行的推导:
s = T ( r ) s = T(r) s=T(r)

r r r为归一化后的颜色值, s s s为经过 T T T变换的值,且 T ( r ) T(r) T(r)在区间上为单调递增函数,即变换后的s,也是从黑到白,反函数:
r = T − 1 ( s ) r = T^{-1}(s) r=T1(s)


F S ( s ) 、 F R ( r ) F_S(s)、F_R(r) FS(s)FR(r)分别为 S S S R R R的分布函数,则有:
F S ( s ) = p { S ≤ s } = p { T ( R ) ≤ s } = p { R ≤ T − 1 ( s ) } = F R ( T − 1 ( s ) ) F_S(s) = p\{S \leq s\} = p\{T(R) \leq s\} = p\{ R \leq T^{-1}(s)\} = F_R(T^{-1}(s)) FS(s)=p{Ss}=p{T(R)s}=p{RT1(s)}=FR(T1(s))

F S ( s ) = F R ( T − 1 ( s ) ) = F R ( r ) ∣ r = T − 1 ( s ) F_S(s) = F_R(T^{-1}(s)) = F_R(r)|_{r = T^{-1}(s)} FS(s)=FR(T1(s))=FR(r)r=T1(s)左右求导, p s ( s ) 、 p r ( r ) p_s(s)、p_r(r) ps(s)pr(r)为概率密度函数:
p s ( s ) = p r ( r ) d r d s ∣ r = T − 1 ( s ) p_s(s) = p_r(r) \frac{dr}{ds}|_{r = T^{-1}(s)} ps(s)=pr(r)dsdrr=T1(s)

d s d r = p r ( r ) p s ( s ) \frac{ds}{dr} = \frac{p_r(r)}{p_s(s)} drds=ps(s)pr(r)

即为所求。
均衡化后可知 p s ( s ) = 1 L − 1 p_s(s) = \frac{1}{L-1} ps(s)=L11,对 d s d r = p r ( r ) p s ( s ) \frac{ds}{dr} = \frac{p_r(r)}{p_s(s)} drds=ps(s)pr(r)进行积分,则:
s = ( L − 1 ) ∫ 0 r p r ( w ) d w = T ( r ) s = (L-1 ) \int_{0}^rp_r(w)dw=T(r) s=(L1)0rpr(w)dw=T(r)

冈萨雷斯是先给出此公式,说这是图像处理中特别重要的变换函数,然后求得用这公式可以得到 p s ( s ) = 1 L − 1 p_s(s) = \frac{1}{L-1} ps(s)=L11。 可是我不知道怎么来的,所以这里我先用结果 p s ( s ) = 1 L − 1 p_s(s) = \frac{1}{L-1} ps(s)=L11,带入求得此公式。
此公式也就解释了为什么累计概率 ( L − 1 ) ∫ 0 r p r ( w ) d w (L-1)\int_{0}^rp_r(w)dw (L1)0rpr(w)dw就是 T ( r ) T(r) T(r),即 s s s。离散化比较好理解,这里不再解释。

说明

输入

假设有一幅4*4 大小8灰度级的图:
在这里插入图片描述
在这里插入图片描述

0123
4444
5555
6756

运算过程

*取整: s k 1 = i n t ( s k + 0.5 ) s_{k1} = int(s_k + 0.5) sk1=int(sk+0.5)

r k r_{_k} rk n n n p r ( r k ) p_r(r_{_k}) pr(rk) ∑ p r ( r ) \sum p_r(r) pr(r) s k 1 s_{k1} sk1 p s ( r k ) p_s(r_{_k}) ps(rk)
011/161/16 = 0.0601/16
111/162/16 = 0.1212/16
211/163/16 = 0.1911/16
311/164/16 = 0.2520
455/169/16 = 0.5645/16
555/1614/16 = 0.8860
611/1615/16 = 0.9375/16
711/16172/16

结果

在这里插入图片描述
在这里插入图片描述

代码实现

用python实现

# -*- coding: utf-8 -*-

"""
    @Date: 2019-10-07
    @Written By: jiangzhigang
    @Description:
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
 

def equalize_hist(img, level):
    img = cv2.copyTo(img, None)
    height = img.shape[0]
    width = img.shape[1]

    color_gray = np.zeros(level, np.float)
    # n
    for i in range(height):
        for j in range(width):
            color_gray[img[i, j]] += 1
    # pr
    are = height * width
    for i in range(level):
        color_gray[i] /= are
    # sum(pr)
    for i in range(1, level):
        color_gray[i] += color_gray[i - 1]
    # sk
    for i in range(level):
        color_gray[i] = color_gray[i] * (level - 1) + 0.5
    # r -> s
    for i in range(height):
        for j in range(width):
            img[i, j] = color_gray[img[i, j]]
    return img


def show_hist(img, level, title="hist"):
    height = img.shape[0]
    width = img.shape[1]

    color_gray = np.zeros(level, np.float)
    # n
    for i in range(height):
        for j in range(width):
            color_gray[img[i, j]] += 1

    # pr
    are = height * width
    for i in range(level):
        color_gray[i] /= are

    x = np.linspace(0, level-1, level)
    y = color_gray
    plt.bar(x, y, 1, alpha=1, color='b')
    plt.title(title)
    plt.show()


img0 = cv2.imread("images/leaf.jpg", 0)
gray = cv2.resize(img0, (400, 400))
# test use
# gray = cv2.resize(img0, (4, 4))
# gray[0][0] = 0
# gray[0][1] = 1
# gray[0][2] = 2
# gray[0][3] = 3
# gray[1][0] = 4
# gray[1][1] = 4
# gray[1][2] = 4
# gray[1][3] = 4
# gray[2][0] = 5
# gray[2][1] = 5
# gray[2][2] = 5
# gray[2][3] = 5
# gray[3][0] = 6
# gray[3][1] = 7
# gray[3][2] = 5
# gray[3][3] = 4

plt.imshow(gray, cmap='gray')
plt.title('resource')
plt.show()
show_hist(gray, 256, "rec_hist")

destination = equalize_hist(gray, 256)
plt.imshow(destination, cmap='gray')
plt.title('destination')
plt.show()
show_hist(destination, 256, 'dst_hist')

# opencv 
destination_ = cv2.equalizeHist(gray)
plt.imshow(destination_, cmap='gray')
plt.title('destination_')
plt.show()
show_hist(destination_, 256, 'op_cv_hist')

结果

原图

在这里插入图片描述
在这里插入图片描述

实现均衡化

在这里插入图片描述
在这里插入图片描述

opencv实现

在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值