推導
岡薩雷斯的書裏給了幾個公式,書中的式3.3-3一直不明白是如何得出的。
下面參考一些文章加上自己理解進行的推導:
爲歸一化後的顏色值,爲經過變換的值,且在區間上爲單調遞增函數,即變換後的s,也是從黑到白,反函數:
設分別爲和的分佈函數,則有:
對左右求導,爲概率密度函數:
即爲所求。
均衡化後可知,對進行積分,則:
岡薩雷斯是先給出此公式,說這是圖像處理中特別重要的變換函數,然後求得用這公式可以得到。 可是我不知道怎麼來的,所以這裏我先用結果,帶入求得此公式。
此公式也就解釋了爲什麼累計概率就是,即。離散化比較好理解,這裏不再解釋。
說明
輸入
假設有一幅4*4 大小8灰度級的圖:
0 | 1 | 2 | 3 |
---|---|---|---|
4 | 4 | 4 | 4 |
5 | 5 | 5 | 5 |
6 | 7 | 5 | 6 |
運算過程
*取整:
0 | 1 | 1/16 | 1/16 = 0.06 | 0 | 1/16 |
1 | 1 | 1/16 | 2/16 = 0.12 | 1 | 2/16 |
2 | 1 | 1/16 | 3/16 = 0.19 | 1 | 1/16 |
3 | 1 | 1/16 | 4/16 = 0.25 | 2 | 0 |
4 | 5 | 5/16 | 9/16 = 0.56 | 4 | 5/16 |
5 | 5 | 5/16 | 14/16 = 0.88 | 6 | 0 |
6 | 1 | 1/16 | 15/16 = 0.93 | 7 | 5/16 |
7 | 1 | 1/16 | 1 | 7 | 2/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實現