1、灰度直方圖概念
灰度直方圖反映一幅影像中各灰度級像素出現的頻率與灰度級的關系,其中,灰度級為橫坐標,頻率為縱坐標,
灰度級:影像中不同灰度的最大數量,灰度級越大,影像亮度范圍越大,
2、灰度直方圖的性質
(1) 只反映影像灰度情況,不反映像素位置;
(2)一幅影像對應唯一的灰度直方圖,但同一灰度直方圖可能對應多幅影像;
(3)一幅影像劃分多個區域,這些區域的直方圖之和為原影像直方圖,
3、灰度直方圖的作用
(1)在使用輪廓線確定物體邊界時,通過直方圖更好地選擇邊界閾值,進行閾值化處理;
(2)對物體與背景有較強的對比的景物分割特別有用;
(3)簡單物體的面積和綜合光密度IOD可以通過直方圖求得,
4、繪制灰度直方圖的兩種方法
方法1、matplotlib:hist(資料源,像素級)
注意:資料源必須是一維陣列,因此需要使用ravel()函式將影像降為一維陣列,
# 方法1:matplotlib——hist()
img = cv2.imread(r'F:\lovergos\OpenCV\Image\dog.jpg')
cv2.imshow('dog',img)
plt.hist(img.ravel(),256)
plt.show()
cv2.waitKey(0)

方法2:cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
常用引數說明:images表示輸入原始影像;channels表示通道,對于灰度圖為[0];彩色圖B、G、R分別用[0]、[1]、[2]表示;mask表示掩碼影像,沒有則使用None;ranges表示像素值范圍,
# 方法2 opencv——calHist()
img = cv2.imread(r'F:\lovergos\OpenCV\Image\ch.png')
img_b = cv2.calcHist(img,[0],None,[256],[0,255]) # B分量灰度圖的直方圖
img_g = cv2.calcHist(img,[1],None,[256],[0,255]) # G分量灰度圖的直方圖
img_r = cv2.calcHist(img,[2],None,[256],[0,255]) # R分量灰度圖的直方圖
plt.plot(img_b,color='b',label='B')
plt.plot(img_g,color='g',label='G')
plt.plot(img_r,color='r',label='R')
plt.legend()
plt.show()


5、直方圖均衡化
基本原理:對在影像中像素個數多的灰度值進行展寬,,而對像素個數少的灰度值進行歸并,從而增大對比度,使影像更加清晰,
直方圖均衡化的實作步驟:
本文以一個簡單例子來實作直方圖均衡化,假設以下影像的灰度級范圍是[0,5]
[1 5 3]
[2 4 5]
[3 1 0]
(1)計算原始影像的灰度直方圖:[1 , 2 , 2 , 1 , 1 , 2]
(2)計算原圖總像素個數 N = 3 * 3 = 9
(3)計算原圖灰度分布頻率:[1/9 , 2/9 , 2/9 , 1/9 , 1/9 , 2/9]
(4)計算原圖累計分布頻率:[1/9 , 3/9 , 5/9 , 6/9 , 7/9 , 9/9]
(5)將累計分布中的元素乘以(L-1)(L-1為灰度級最大值,本例中L-1=5),再四舍五入,以使得均衡化后的影像的灰度級與原始影像一致,
s[0] = 1/9 * 5 = 0; s[1] = 3/9 * 5 = 2; s[2] = 5/9 * 5 = 3;
s[3] = 6/9 * 5 = 3; s[4] = 7/9 * 5 = 4; s[5] = 9/9 * 5 = 5;
s = [0 , 2 , 3 , 3 , 4 , 5]
注意:原圖中的值作為s的下標,對應的值即為均衡化后的結果:
[2 5 3]
[3 4 5]
[3 2 0]
為了更好的演示演算法原理,本文首先通過自行編碼實作灰度影像的直方圖均衡化,然后再對比opencv實作均衡化方法來驗證,
(1)首先讀取一張灰度圖,并提取其高度和寬度
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(r'F:\lovergos\OpenCV\Image\dog.jpg',cv2.IMREAD_GRAYSCALE) # 讀取一張灰度圖
height,width = img.shape
灰度影像如下:

(2)統計每個灰度像素值的累計數目,構建初始灰度直方圖
num_pixel = np.zeros(256) # 創建長度為256的串列,用來保存每個像素值的數目,初始化為0
# 統計串列中某個值出現的次數
for i in range(height):
for j in range(width):
k = img[i][j] # 得到當前像素值
num_pixel[k] = num_pixel[k]+1 # 當前像素值的個數增加1(k的大小對應num_pixel的下標)
# 顯示灰度直方圖
# plt.bar(np.arange(0,256),num_pixel)
# plt.show()
(3)計算原圖灰度分布頻率
prob_pixel = np.zeros(256)
for i in range(0,256):
prob_pixel[i] = num_pixel[i]/(height*width) # 出現次數/總數
(4)計算原圖累積分布頻率:呼叫np.cumsum()
cum_pixel = np.cumsum(prob_pixel)
(5)將累計分布中的元素乘以(L-1)(此處為255),再四舍五入,以使得均衡化后的影像的灰度級與原始影像一致,
for i in range(len(cum_pixel)):
cum_pixel[i] = int(cum_pixel[i]*255+0.5) # python中直接取整不會四舍五入,因此先+0.5再取整表示四舍五入
(6)根據cum_pixel得到形式和原圖相同的輸出
out_img = img # 保持和原圖格式相同
for m in range(0,height):
for n in range(0,width):
k = img[m][n]
out_img[m][n] = cum_pixel[img[m][n]] # out_img中新的值,保存在cum_pixel中,由映射關系知,img[m][n]為對應下標
通過這種方式均衡化得到的新圖為:

(7)驗證:使用opencv中的函式 cv2.equalizeHist(image)
equ = cv2.equalizeHist(img)
print(equ)
cv2.imshow('out_img',equ)
cv2.waitKey(0)

通過觀察,兩種方法得到的結果是一致的,但不得不說opencv的方法還是簡單太多,
參考文獻
[1] 影像的灰度直方圖_逸凌Time-CSDN博客_灰度直方圖
[2] 數字影像處理(15): 灰度直方圖(matplotlib 和OpenCV 繪制直方圖)_TechArtisan6的博客-CSDN博客[3]【影像處理演算法】直方圖均衡化_GQ-CSDN博客_直方圖均衡化
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375069.html
標籤:其他
上一篇:【論文總結】Damage-Map Estimation Using UAV Images and Deep Learning Algorithms for DMS
下一篇:VATT 論文學習筆記
