python+OpenCv直方圖(灰度直方圖、掩膜的應(yīng)用、直方圖均衡化、自適應(yīng)直方圖均衡化)
一、灰度直方圖
概念:
圖像直方圖是表示數(shù)字圖像中亮度分布的直方圖,標(biāo)繪了圖像中每個亮度值的像素個數(shù)。
這種直方圖中,橫坐標(biāo)的左側(cè)為較暗的區(qū)域,而右側(cè)為較亮的區(qū)域。因此一張較暗圖片的直方圖中的數(shù)據(jù)多集中于左側(cè)和中間部分,而整體明亮、只有少量陰影的圖像則相反。如圖:
注意:圖像直方圖是根據(jù)灰度圖進(jìn)行繪制的,而不是彩色圖像。
圖像直方圖的術(shù)語:
dims:需要統(tǒng)計的特征數(shù)目。
(比如,如果僅統(tǒng)計了灰度值,則dims=1,如果統(tǒng)計了BGR三色,則dims=3)
bins:每個特征空間子區(qū)段的數(shù)目。
(如下圖的直方圖中,每一豎條表示某一值或一區(qū)間,則該直方圖的bins=16)
range:要統(tǒng)計特征的取值范圍。
(如下圖中,我們將[0,255]區(qū)間分成了16個子區(qū)間,其中range=[0,255])
直方圖的意義:
直方圖是圖像中像素強度分布的圖形表達(dá)方式。
它統(tǒng)計了每一個強度值所具有的像素個數(shù)。
不同的圖像的直方圖可能是相同的
OpenCv API:
cv2.calcHist(images, channels, mask, histSize, ranges)
參數(shù):
- images:原圖像。當(dāng)傳入函數(shù)時應(yīng)該用中括號 [] 括起來,例如:[img]
- channels:如果輸入圖像是灰度圖,它的值就是[0];如果是彩色圖像的話,傳入的參數(shù)可以是[0],[1],[2]它們分別對應(yīng)著通道B,G,R。
- mask:掩模圖像。要統(tǒng)計整幅圖像的直方圖就把它設(shè)為None。但是如果你想統(tǒng)計圖像某一部分的直方圖的話,你就需要制作一個掩模圖像,并使用它。
- histSize:bins的數(shù)目。也應(yīng)該用中括號括起來,例如:[256]。
- ranges:像素值范圍。通常為[0,256]。
代碼編寫:
import cv2 as cv import matplotlib.pyplot as plt src = cv.imread("E:\\view.jpg", 0) # 直接以灰度圖方式讀入 img = src.copy() # 統(tǒng)計灰度圖 greyScale_map = cv.calcHist([img], [0], None, [256], [0, 256]) # 繪制灰度圖 plt.figure(figsize=(10, 6), dpi=100) plt.plot(greyScale_map) plt.grid() plt.show()
二、掩膜的應(yīng)用
原理:
掩膜是用選定的圖像、圖形或物體,對要處理的圖像進(jìn)行遮擋,來控制圖像處理的區(qū)域。
在數(shù)字圖像處理中,我們通常使用二維矩陣數(shù)組進(jìn)行掩膜。掩膜是由0和1組成一個二進(jìn)制圖像,利用該掩膜圖像要處理的圖像進(jìn)行掩膜,其中1值的區(qū)域被處理,0值區(qū)域被屏蔽,不會處理。
應(yīng)用:
掩膜的主要用途是:
- 提取感興趣區(qū)域:用預(yù)先制作的感興趣區(qū)掩膜與待處理圖像進(jìn)行”與“操作,得到感興趣區(qū)圖像,感興趣區(qū)內(nèi)圖像值保持不變,而區(qū)外圖像值都為0。
- 屏蔽作用︰用掩膜對圖像上某些區(qū)域作屏蔽,使其不參加處理或不參加處理參數(shù)的計算,或僅對屏蔽區(qū)作處理或統(tǒng)計。
- 結(jié)構(gòu)特征提取︰用相似性變量或圖像匹配方法檢測和提取圖像中與掩模相似的結(jié)構(gòu)特征。
- ·特殊形狀圖像制作。
掩膜在遙感影像處理中使用較多,當(dāng)提取道路或者河流,或者房屋時,通過一個掩膜矩陣來對圖像進(jìn)行像素過濾,然后將我們需要的地物或者標(biāo)志突出顯示出來。
代碼編寫:
import cv2 as cv import matplotlib.pyplot as plt import numpy as np src = cv.imread("E:\\view.jpg", 0) # 直接以灰度圖方式讀入 img = src.copy() # 創(chuàng)建蒙版 mask = np.zeros(img.shape[:2], np.uint8) mask[700:1000, 100:400] = 1 # 掩膜 masked_img = cv.bitwise_and(img, img, mask=mask) # 與操作 # 統(tǒng)計掩膜后圖像的灰度圖 mask_histr = cv.calcHist([img], [0], mask, [256], [0, 256]) # 顯示圖像 fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100) axes[0][0].imshow(img, cmap=plt.cm.gray) axes[0][0].set_title("原圖") axes[0][1].imshow(mask, cmap=plt.cm.gray) axes[0][1].set_title("蒙版數(shù)據(jù)") axes[1][0].imshow(masked_img, cmap=plt.cm.gray) axes[1][0].set_title("掩膜后圖像") axes[1][1].plot(mask_histr) axes[1][1].grid() axes[1][1].set_title("掩膜后圖像的灰度直方圖") plt.show()
三、直方圖均衡化
原理:
想象一下,如果一副圖像中的大多數(shù)像素點的像素值都集中在某一個小的灰度值值范圍之內(nèi)會怎樣呢?如果一幅圖像整體很亮,那所有的像素值的取值個數(shù)應(yīng)該都會很高。所以應(yīng)該把它的直方圖做一個橫向拉伸(如下圖),就可以擴大圖像像素值的分布范圍,提高圖像的對比度,這就是直方圖均衡化要做的事情。
“直方圖均衡化"是把原始圖像的灰度直方圖從比較集中的某個灰度區(qū)間變成在更廣泛灰度范圍內(nèi)的分布。直方圖均衡化就是對圖像進(jìn)行非線性拉伸,重新分配圖像像素值,使一定灰度范圍內(nèi)的像素數(shù)量大致相同。
應(yīng)用:
提高圖像整體的對比度。
特別是有用數(shù)據(jù)的像素值分布比較接近時,在X光圖像中使用廣泛,可以提高骨架結(jié)構(gòu)的顯示,另外在曝光過度或不足的圖像中可以更好的突出細(xì)節(jié)。
OpenCv API:
cv2.equalizeHist(img)
參數(shù):
img:輸入的灰度圖
代碼編寫:
import cv2 as cv import matplotlib.pyplot as plt import numpy as np src = cv.imread("E:\\qi.png", 0) # 直接以灰度圖方式讀入 img = src.copy() # 均衡化處理 dst = cv.equalizeHist(img) # 顯示圖像 fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100) axes[0].imshow(img, cmap=plt.cm.gray) axes[0].set_title("原圖") axes[1].imshow(dst, cmap=plt.cm.gray) axes[1].set_title("均衡化后的圖像") plt.show()
四、自適應(yīng)的直方圖均衡化
由來:
上述的直方圖均衡化,我們考慮的是圖像的全局對比度。的確在進(jìn)行完直方圖均衡化之后,圖片背景的對比度被改變了,但在許多情況下,這樣做的效果并不好,因為均衡化之后的圖像很有可能發(fā)生局部過亮或者局部過暗的情況,從而造成數(shù)據(jù)信息的丟失。
原理:
- 將整幅圖像分成很多小塊,這些小塊被稱為“tiles”(在 OpenCV中tiles的大小默認(rèn)是8x8),然后再對每一個小塊分別進(jìn)行直方圖均衡化。(所以在每一個的區(qū)域中,直方圖會集中在某一個小的區(qū)域中)。
- 如果有噪聲的話,噪聲會被放大。為了避免這種情況的出現(xiàn)要使用對比度限制。對于每個小塊來說,如果直方圖中的 bin超過對比度的上限的話,就把其中的像素點均勻分散到其他bins 中,然后在進(jìn)行直方圖均衡化。
最后,為了去除每一個小塊之間的邊界,再使用雙線性差值,對每一小塊進(jìn)行拼接。
OpenCv API:
clahe = cv.createCLAHE(clipLimit, tileGridSize) dst = clahe.apply(img)
參數(shù):
- clipLimit:對比度限制,默認(rèn)是40
- tileGridSize:分塊的大小,默認(rèn)為8*8 代碼編寫:
import cv2 as cv import matplotlib.pyplot as plt import numpy as np src = cv.imread("E:\\qi.png", 0) # 直接以灰度圖方式讀入 img = src.copy() # 創(chuàng)建一個自適應(yīng)均衡化的對象,并應(yīng)用于圖像 clahe = cv.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8)) dst = clahe.apply(img) # 顯示圖像 fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100) axes[0].imshow(img, cmap=plt.cm.gray) axes[0].set_title("原圖") axes[1].imshow(dst, cmap=plt.cm.gray) axes[1].set_title("自適應(yīng)均衡化后的圖像") plt.show()
到此這篇關(guān)于python+OpenCv直方圖(灰度直方圖、掩膜的應(yīng)用、直方圖均衡化、自適應(yīng)直方圖均衡化)的文章就介紹到這了,更多相關(guān)python OpenCv直方圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實現(xiàn)列表轉(zhuǎn)換成字典數(shù)據(jù)結(jié)構(gòu)的方法
這篇文章主要介紹了Python實現(xiàn)列表轉(zhuǎn)換成字典數(shù)據(jù)結(jié)構(gòu)的方法,結(jié)合實例形式分析了Python數(shù)值類型轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2016-03-03Python協(xié)程 yield與協(xié)程greenlet簡單用法示例
這篇文章主要介紹了Python協(xié)程 yield與協(xié)程greenlet簡單用法,簡要講述了協(xié)程的概念、原理,并結(jié)合實例形式分析了Python協(xié)程 yield與協(xié)程greenlet基本使用方法,需要的朋友可以參考下2019-11-11