Python OpenCV直方圖均衡化詳解
前言
圖像處理技術(shù)是計算機視覺項目的核心,通常是計算機視覺項目中的關(guān)鍵工具,可以使用它們來完成各種計算機視覺任務(wù)。在本文中,將介紹如何使用 OpenCV
函數(shù) cv2.equalizeHist()
執(zhí)行直方圖均衡,并將其應(yīng)用于灰度和彩色圖像,cv2.equalizeHist()
函數(shù)將亮度歸一化并提高圖像的對比度。
灰度直方圖均衡化
使用 cv2.equalizeHist()
函數(shù)來均衡給定灰度圖像的對比度:
# 加載圖像并轉(zhuǎn)換為灰度圖像 image = cv2.imread('example.png') gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256]) # 直方圖均衡化 gray_image_eq = cv2.equalizeHist(gray_image) # 直方圖均衡化后的圖像直方圖 hist_eq = cv2.calcHist([gray_image_eq], [0], None, [256], [0, 256])
為了深入了解直方圖均衡,我們對原始灰度圖像進行修改,為圖像的每個像素添加/減去 30,并計算直方圖均衡前后的直方圖:
M = np.ones(gray_image.shape, dtype='uint8') * 30 # 為圖像的每個像素添加 30 added_image = cv2.add(gray_image, M) hist_added_image = cv2.calcHist([added_image], [0], None, [256], [0, 256]) # 直方圖均衡化 added_image_eq = cv2.equalizeHist(gray_image_eq) hist_eq_added_image = cv2.calcHist([added_image_eq], [0], None, [256], [0, 256]) # 為圖像的每個像素減去 30 subtracted_image = cv2.subtract(gray_image, M) hist_subtracted_image = cv2.calcHist([subtracted_image], [0], None, [256], [0, 256]) # 直方圖均衡化 subtracted_image_eq = cv2.equalizeHist(subtracted_image) hist_eq_subtracted_image = cv2.calcHist([subtracted_image_eq], [0], None, [256], [0, 256])
最后,繪制所有這些圖像:
def show_img_with_matplotlib(color_img, title, pos): img_RGB = color_img[:, :, ::-1] ax = plt.subplot(3, 4, pos) plt.imshow(img_RGB) plt.title(title, fontsize=8) plt.axis('off') def show_hist_with_matplotlib_gray(hist, title, pos, color): ax = plt.subplot(3, 4, pos) plt.xlabel("bins") plt.ylabel("number of pixels") plt.xlim([0, 256]) plt.plot(hist, color=color) # 可視化 show_img_with_matplotlib(cv2.cvtColor(gray_image, cv2.COLOR_GRAY2BGR), "gray", 1) show_hist_with_matplotlib_gray(hist, "grayscale histogram", 2, 'm') show_img_with_matplotlib(cv2.cvtColor(added_image, cv2.COLOR_GRAY2BGR), "gray lighter", 5) show_hist_with_matplotlib_gray(hist_added_image, "grayscale histogram", 6, 'm') show_img_with_matplotlib(cv2.cvtColor(subtracted_image, cv2.COLOR_GRAY2BGR), "gray darker", 9) show_hist_with_matplotlib_gray(hist_subtracted_image, "grayscale histogram", 10, 'm') # 其他圖像的可視化方法類似,不再贅述 # ...
程序運行的輸出如下圖所示:
在上圖中,我們可以看到三個均衡化后的圖像非常相似,這也反映在均衡化后的直方圖中,這是因為直方圖均衡化傾向于標準化圖像的亮度,同時增加對比度。
顏色直方圖均衡化
使用相同的方法,我們可以在彩色圖像中執(zhí)行直方圖均衡,將直方圖均衡應(yīng)用于 BGR 圖像的每個通道(雖然這不是彩色圖像直方圖均衡的最佳方法),創(chuàng)建 equalize_hist_color()
函數(shù),使用 cv2.split()
分割 BGR
圖像并將 cv2.equalizeHist()
函數(shù)應(yīng)用于每個通道,最后,使用 cv2.merge()
合并結(jié)果通道:
def equalize_hist_color(img): # 使用 cv2.split() 分割 BGR 圖像 channels = cv2.split(img) eq_channels = [] # 將 cv2.equalizeHist() 函數(shù)應(yīng)用于每個通道 for ch in channels: eq_channels.append(cv2.equalizeHist(ch)) # 使用 cv2.merge() 合并所有結(jié)果通道 eq_image = cv2.merge(eq_channels) return eq_image
接下來,將此函數(shù)應(yīng)用于三個不同的圖像:原始 BGR 圖像、將原始圖像的每個像素值添加 10、將原始圖像的每個像素值減去 10,并計算直方圖均衡前后的直方圖:
# 加載圖像 image = cv2.imread('example.png') # 計算直方圖均衡前后的直方圖 hist_color = hist_color_img(image) image_eq = equalize_hist_color(image) hist_image_eq = hist_color_img(image_eq) M = np.ones(image.shape, dtype="uint8") * 10 # 為圖像的每個像素添加 10 added_image = cv2.add(image, M) # 直方圖均衡前后的直方圖 hist_color_added_image = hist_color_img(added_image) added_image_eq = equalize_hist_color(added_image) hist_added_image_eq = hist_color_img(added_image_eq) # 為圖像的每個像素減去 10 subtracted_image = cv2.subtract(image, M) # 直方圖均衡前后的直方圖 hist_color_subtracted_image = hist_color_img(subtracted_image) subtracted_image_eq = equalize_hist_color(subtracted_image) hist_subtracted_image_eq = hist_color_img(subtracted_image_eq)
最后,繪制所有這些圖像:
def show_img_with_matplotlib(color_img, title, pos): img_RGB = color_img[:, :, ::-1] ax = plt.subplot(3, 4, pos) plt.imshow(img_RGB) plt.title(title, fontsize=8) plt.axis('off') def show_hist_with_matplotlib_rgb(hist, title, pos, color): ax = plt.subplot(3, 4, pos) plt.xlabel("bins") plt.ylabel("number of pixels") plt.xlim([0, 256]) for (h, c) in zip(hist, color): plt.plot(h, color=c) # 可視化 show_img_with_matplotlib(image, "image", 1) show_hist_with_matplotlib_rgb(hist_color, "color histogram", 2, ['b', 'g', 'r']) show_img_with_matplotlib(added_image, "image lighter", 5) show_hist_with_matplotlib_rgb(hist_color_added_image, "color histogram", 6, ['b', 'g', 'r']) show_img_with_matplotlib(subtracted_image, "image darker", 9) show_hist_with_matplotlib_rgb(hist_color_subtracted_image, "color histogram", 10, ['b', 'g', 'r']) # 其他圖像的可視化方法類似,不再贅述 # ...
將直方圖均衡化應(yīng)用于 BGR
圖像的每個通道并不是顏色直方圖均衡化的好方法,這是由于 BGR
色彩空間的加性特性導(dǎo)致彩色圖像的顏色變化很大。由于我們獨立地改變?nèi)齻€通道中的亮度和對比度,因此在合并均衡通道時,這可能會導(dǎo)致圖像中出現(xiàn)新的色調(diào),正如上圖所看到的那樣。
一種顏色直方圖均衡化更好的方法是將 BGR 圖像轉(zhuǎn)換為包含亮度/強度通道的色彩空間( Yuv
、Lab
、HSV
和 HSL
)。然后,只在亮度通道上應(yīng)用直方圖均衡,最后合并通道并將它們轉(zhuǎn)換回 BGR
顏色空間,以 HSV
空間為例,創(chuàng)建 equalize_hist_color_hsv()
函數(shù)實現(xiàn)上述顏色直方圖歸一化方法:
def equalize_hist_color_hsv(img): H, S, V = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV)) eq_V = cv2.equalizeHist(V) eq_image = cv2.cvtColor(cv2.merge([H, S, eq_V]), cv2.COLOR_HSV2BGR) return eq_image
接下來,將此函數(shù)應(yīng)用于三個不同的圖像:原始 BGR 圖像、將原始圖像的每個像素值添加 10、將原始圖像的每個像素值減去 10,并計算直方圖均衡前后的直方圖:
hist_color = hist_color_img(image) # 計算直方圖均衡前后的直方圖 image_eq = equalize_hist_color_hsv(image) hist_image_eq = hist_color_img(image_eq) M = np.ones(image.shape, dtype="uint8") * 10 # 為圖像的每個像素添加 10 added_image = cv2.add(image, M) hist_color_added_image = hist_color_img(added_image) # 直方圖均衡前后的直方圖 added_image_eq = equalize_hist_color_hsv(added_image) hist_added_image_eq = hist_color_img(added_image_eq) # 為圖像的每個像素減去 10 subtracted_image = cv2.subtract(image, M) hist_color_subtracted_image = hist_color_img(subtracted_image) # 直方圖均衡前后的直方圖 subtracted_image_eq = equalize_hist_color_hsv(subtracted_image) hist_subtracted_image_eq = hist_color_img(subtracted_image_eq)
最后,繪制所有這些圖像:
# show_img_with_matplotlib() 和 show_hist_with_matplotlib_rgb() 函數(shù)與上一示例相同 show_img_with_matplotlib(image, "image", 1) show_hist_with_matplotlib_rgb(hist_color, "color histogram", 2, ['b', 'g', 'r']) show_img_with_matplotlib(added_image, "image lighter", 5) show_hist_with_matplotlib_rgb(hist_color_added_image, "color histogram", 6, ['b', 'g', 'r']) # 其他圖像的可視化方法類似,不再贅述 # ...
由上圖可以看出,僅均衡 HSV
圖像的 V
通道得到的結(jié)果比均衡 BGR
圖像的所有通道的效果要好很多,也可以將這種方法用于其他包含亮度/強度通道的色彩空間( Yuv
、Lab
和 HSL
)。
以上就是Python OpenCV直方圖均衡化詳解的詳細內(nèi)容,更多關(guān)于OpenCV直方圖均衡化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python 基于DDT實現(xiàn)數(shù)據(jù)驅(qū)動測試
這篇文章主要介紹了python 基于DDT實現(xiàn)數(shù)據(jù)驅(qū)動測試的方法,幫助大家更好的理解和學(xué)習使用python,感興趣的朋友可以了解下2021-02-02Pandas?Groupby之在Python中匯總、聚合和分組數(shù)據(jù)的示例詳解
GroupBy是一個非常簡單的概念,我們可以創(chuàng)建一個類別分組,并對這些類別應(yīng)用一個函數(shù),本文給大家介紹Pandas?Groupby之如何在Python中匯總、聚合和分組數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧2023-07-07python 實現(xiàn)數(shù)字字符串左側(cè)補零的方法
今天小編就為大家分享一篇python 實現(xiàn)數(shù)字字符串左側(cè)補零的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12