opencv 繪制圖像直方圖,實現直方圖均衡化,自適應均衡化


直方圖

直方圖簡單來說就是圖像中每個像素值的個數統計,比如說一副灰度圖中像素值為0的有多少個,1的有多少個……直方圖是一種分析圖像的手段:
圖像->直方圖,bins=7

直方圖計算

opencv庫計算直方圖

使用 cv.calcHist(images, channels, mask, histSize, ranges) 計算,其中:
參數1:要計算的原圖,以方括號的形式傳入,如:[img]
參數2:選擇圖像的某個通道,計算直方圖,灰度圖像寫[0]
參數3:要計算的區域,計算整幅圖的話,寫None
參數4:直方圖橫坐標數目
參數5:要計算的像素范圍,一般為[0,255]

例如:hist = cv.calcHist([img], [0], None, [256], [0, 255])

numpy庫計算直方圖

可用Numpy中的函數計算直方圖,其中ravel()函數將二維矩陣展平變成一維數組:
hist, bins = np.histogram(img.ravel(), 255, [0, 255])
另一種更高效的方式:
hist = np.bincount(img.ravel(), minlength=256)

直方圖繪制

Matplotlib庫自帶了一個計算並繪制直方圖的功能,不需要用到上面的函數:
plt.hist(img.ravel(), 256, [0, 255])
plt.show()

當然,也可以用前面計算出來的結果繪制:
plt.plot(hist)
plt.show()

實驗

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img = cv.imread('hist.jpg', 0)
hist = cv.calcHist([img], [0], None, [256], [0, 255])

plt.plot(hist)
plt.show()

實驗結果

原圖
原圖像的直方圖
從直方圖上可以看到圖片的大部分區域集中在150偏白的附近,這其實並不是很好的效果,下面我們來看看如何改善它。

直方圖均衡化

一副效果好的圖像通常在直方圖上的分布比較均勻,直方圖均衡化就是用來改善圖像的全局亮度和對比度。其實從觀感上就可以發現,前面那幅圖對比度不高,偏灰白。對均衡化算法感興趣的同學可參考:直方圖均衡化算法及python實現
圖解圖像直方圖均衡化

opencv中實現圖像直方圖均衡化

equ = cv.equalizeHist(img)

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img = cv.imread('hist.jpg', 0)
img_eq = cv.equalizeHist(img)
hist = cv.calcHist([img], [0], None, [256], [0, 255])
hist_eq = cv.calcHist([img_eq], [0], None, [256], [0,255])

plt.figure(1)

plt.subplot(2,2,1)
plt.imshow(img,cmap='gray')
plt.subplot(2,2,2)
plt.imshow(img_eq,cmap='gray')
plt.subplot(2,2,3)
plt.plot(hist)
plt.subplot(2,2,4)
plt.plot(hist_eq)

plt.show()

代碼輸出結果,可以看到均衡化后圖片的亮度和對比度效果明顯好於原圖

matlab圖像直方圖均衡化

請參考一篇優秀個文章:matlab實現圖像直方圖均衡化

直方圖自適應均衡化

不難看出來,直方圖均衡化是應用於整幅圖片的,會有什么問題呢?看下圖:
左圖:原圖;右圖:直方圖均衡化后
很明顯,因為全局調整亮度和對比度的原因,臉部太亮,大部分細節都丟失了。
自適應均衡化就是用來解決這一問題的:它在每一個小區域內(默認8×8)進行直方圖均衡化。當然,如果有噪點的話,噪點會被放大,需要對小區域內的對比度進行了限制,所以這個算法全稱叫:對比度受限的自適應直方圖均衡化CLAHE(Contrast Limited Adaptive Histogram Equalization)。

實現直方圖自適應均衡化

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img = cv.imread('tsukuba.jpg', 0)
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)

plt.subplot(1,2,1)
plt.imshow(img,cmap='gray')
plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2)
plt.imshow(cl1,cmap='gray')
plt.title('Adaptive Histogram Equalization')
plt.xticks([]),plt.yticks([])

plt.show()

實驗結果

左圖:源圖像;右圖:自適應均衡化后圖像


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM