直方圖是一種統(tǒng)計圖,顯示了圖像中每個灰度級別(或顏色通道)的像素數(shù)量。通過分析圖像的直方圖,可以獲得關(guān)于圖像對比度、亮度和顏色分布等方面的重要信息。
一、直方圖的意義
橫坐標(biāo)是圖像中各像素點的灰度級,
縱坐標(biāo)是具有該灰度級(像素值)的像素個數(shù)。
了解圖像的對比度、亮度和色彩分布等信息。你可以使用OpenCV中的函數(shù)來計算和繪制圖像的直方圖,從而進行圖像增強、顏色校正和特征提取等操作。
RANGE:強度值。表示要統(tǒng)計的灰度級范圍,一般為[0, 255]。0 對應(yīng)的是黑色,255 對應(yīng)的是白色。
BINS:參數(shù)子集的數(shù)目。在處理數(shù)據(jù)的過程中,有時需要將眾多的數(shù)據(jù)劃分為若干個組,再進行分析。
DIMS:表示在繪制直方圖時,收集的參數(shù)的數(shù)量。一般情況下,直方圖中收集的數(shù)據(jù)
只有一種,就是灰度級。因此,該值為 1。
二、繪制直方圖
2.1 直接使用Matplotlib.pyplot.hist()
import matplotlib.pyplot as plt
plt.hist(X,BINS)
? X:數(shù)據(jù)源,必須是一維的。圖像通常是二維的,需要使用 ravel()函數(shù)將圖像處理為一
維數(shù)據(jù)源以后,再作為參數(shù)使用。
? BINS:BINS 的具體值,表示灰度級的分組情況。
使用函數(shù) ravel()對 a 進行降維處理:b = a.ravel()
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('img/resizeImgx.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
2.2 OpenCV的方法 cv2.calcHist()函數(shù)統(tǒng)計圖像直方圖
我們就接下來使用的是灰度圖的直方圖,用其標(biāo)記圖像中每個明亮值的個數(shù)。cv.calcHist(img,chamels,mask,histSize,ranges[,hist[,accmulate]])
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:BIN 的數(shù)目。也應(yīng)該用中括號括起來,例如:[256]。
.
ranges: 像素值范圍,通常為 [0,256]
.
accumulate: 可選參數(shù),用于累積直方圖。如果設(shè)置為 True,則直方圖在每次調(diào)用函數(shù)時都會被累積
(1)隨機數(shù)的形式模擬
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
x = np.random.randint(0, 256, (105, 105), dtype=np.uint8)
x=cv.imread("img1/test_img.jpg",0)
print("x")
x
plt.imshow(x, cmap="gray")
print("直方圖")
y = x.ravel()
# 注意一定要是灰度的才是灰度的顯示出來明亮關(guān)系的直方圖
plt.hist(y, bins=256, range=(0, 256))
y = cv.calcHist([x], [0], None, [256], [0, 256])
plt.figure(figsize=(10, 8))
plt.plot(y)
plt.show()
(2)彩色圖片
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
x=cv.imread("img1/test_img.jpg")
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv.calcHist([x],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
(3)灰度圖像
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
x=cv.imread("img1/test_img.jpg",0)
# print("直方圖")
y = x.ravel()
# 注意一定要是灰度的才是灰度的顯示出來明亮關(guān)系的直方圖
plt.hist(y, bins=256, range=(0, 256))
y = cv.calcHist([x], [0], None, [256], [0, 256])
plt.figure(figsize=(5, 4))
plt.plot(y)
plt.show()
2.3 對比顯示直方圖的方法
2.3.1 柱狀圖和折線圖
plt.hist函數(shù)是用來創(chuàng)建柱狀圖的,它將數(shù)據(jù)按照指定的bins和range進行分組,并以柱狀圖的形式展示各個分組的頻數(shù)。
plt.plot函數(shù)則是用來創(chuàng)建折線圖的,它將給定的數(shù)據(jù)點連接起來,形成一條折線。
2.3.2 兩種不同庫的函數(shù)
cv.calcHist
和 plt.hist
都與圖像處理和直方圖相關(guān),但它們是不同的庫中的不同函數(shù)。
-
cv.calcHist:
- 庫: OpenCV (cv2)
- 用途: 用于計算圖像的直方圖。
-
語法:
hist = cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
-
參數(shù):
-
images
: 輸入圖像列表。 -
channels
: 通道的索引。例如,對于灰度圖像,通常為 [0];對于彩色圖像,可以是 [0, 1, 2] 分別表示藍色、綠色和紅色通道。 -
mask
: 掩碼圖像。如果沒有,則可以傳遞None
。 -
histSize
: 直方圖的 bin 數(shù)量。 -
ranges
: 像素值的范圍,通常為 [0, 256]。
-
-
plt.hist:
- 庫: Matplotlib (plt)
- 用途: 用于繪制直方圖。
-
語法:
n, bins, patches = plt.hist(x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, *, data=None, **kwargs)
-
參數(shù):
-
x
: 數(shù)據(jù)集。 -
bins
: 直方圖的 bin 數(shù)量。 -
hist(數(shù)據(jù)源【一維x.ravel()】,像素級【一般256】)
-
range
: 數(shù)據(jù)值的范圍。 - 其他參數(shù)用于調(diào)整直方圖的外觀,如顏色、標(biāo)簽等。
-
所以,cv.calcHist
用于計算圖像的直方圖,而 plt.hist
用于繪制直方圖。通常,你可以使用 cv.calcHist
計算直方圖,然后使用 plt.hist
繪制計算得到的直方圖。
cv2.calcHist函數(shù)用于計算圖像的直方圖,它接受圖像、通道索引、蒙版、直方圖的大小和像素值范圍作為參數(shù),并返回計算得到的直方圖。
而plt.hist函數(shù)是用于繪制直方圖的函數(shù),它接受圖像數(shù)據(jù)、直方圖的箱數(shù)(bin數(shù))、像素值范圍等參數(shù),并直接在圖像上繪制直方圖。
2.4 使用掩模繪制直方圖
掩膜是用選定的圖像、圖形或物體,對要處理的圖像進行遮擋,來控制圖像 處理的區(qū)域。
OpenCV中,掩膜(Mask)通常用于指定要處理的圖像的特定區(qū)域。掩膜是一個與圖像大小相同的二進制圖像,其中像素值為1表示要處理的區(qū)域,而像素值為0表示要忽略的區(qū)域。
掩膜的主要用途是:提取感興趣區(qū)域:用預(yù)先制作的感興趣區(qū)掩模與待處理圖像進行”與“操作,得到感興趣區(qū)圖像,感興趣區(qū)內(nèi)圖像值保持不變,而區(qū)外圖像值都為0.
屏蔽作用:用掩模對圖像上某些區(qū)域作屏蔽,使其不參加處理或不參加處理參數(shù)的計算,或僅對屏蔽區(qū)作處理或統(tǒng)計。
結(jié)構(gòu)特征提?。河孟嗨菩宰兞炕驁D像匹配方法檢測和提取圖像中與掩模相似的結(jié)構(gòu)特征。
然后將我們需要的地物或者標(biāo)志突出顯示出來
掩模處理
構(gòu)造掩模圖像
使用掩模繪制直方圖
自身與運算,再掩膜與運算
maskedImage=cv.bitwise_and(imgOriginal,imgOriginal,mask=mask)
可以直接
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
imgOriginal=cv.imread("Pic/cc.jpg")
# 創(chuàng)建蒙版
mask=np.zeros(imgOriginal.shape[:2],dtype=np.uint8)
mask[400:600,600:800]=255
plt.imshow(mask,cmap=plt.cm.gray)
print("mask")
print(mask)
plt.colorbar()
# 創(chuàng)建蒙版圖像
maskedImage=cv.bitwise_and(imgOriginal,imgOriginal,mask=mask)
print("maskedImage")
plt.imshow(maskedImage,cmap=plt.cm.gray)
plt.colorbar()
# 統(tǒng)計掩膜后的灰度
mask_histr=cv.calcHist([imgOriginal],[0],mask,[256],[0,256])
# 展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8),dpi=100)
axes[0,0].imshow(imgOriginal,cmap=plt.cm.gray)
axes[0,0].set_title("Original")
axes[0,1].imshow(mask,cmap=plt.cm.gray)
axes[0,1].set_title("Mask")
axes[1,0].imshow(maskedImage,cmap=plt.cm.gray)
axes[1,0].set_title("Masked Image")
axes[1,1].plot(mask_histr)
axes[1,1].set_title("Histogram")
plt.show()
2.5 直方圖均衡化
“直方圖均衡化”是把原始圖像的灰度直方圖從比較集中的某個灰度區(qū)間變成在更廣泛灰度范圍內(nèi)的分布。
直方圖均衡化就是對圖像進行非線性拉伸,重新分配圖像像素值,使一定灰度范圍內(nèi)的像素數(shù)量大致相同。
這種方法提高圖像整體的對比度,特別是有用數(shù)據(jù)的像素值分布比較接近時。
在X光圖像中使用廣泛,可以提高骨架結(jié)構(gòu)的顯示,
另外在曝光過度或不足的圖像中可以更好的突出細節(jié)。
2.5.1 實現(xiàn)直方圖均衡化過程
轉(zhuǎn)化與合并–就是轉(zhuǎn)化為下一級別的了
累計直方圖的概率像素級。
然后得到的每一個舊像素級根據(jù)自身的累計直方圖的概率像素級。成為新的像素級
GPT給的過程
2.5.2 函數(shù)cv2.equalizeHist()
實現(xiàn)直方圖均衡化。
函數(shù)
dst = cv2.equalizeHist( src )
實現(xiàn)
# 提高圖像對比度
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread("img1/test_img.jpg", 0)
# 均衡化
dst = cv.equalizeHist(img1)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
axes[0, 0].imshow(img1, cmap=plt.cm.gray)
axes[0, 0].set_title("Original")
axes[0, 1].hist(img1.ravel(), 256, [0, 256])
axes[1, 0].imshow(dst, cmap=plt.cm.gray)
axes[1, 0].set_title("Histogram Equalization")
axes[1, 1].hist(dst.ravel(), 256, [0, 256])
axes[1, 1].set_title("Histogram")
plt.show()
2.6 自適應(yīng)均衡化
圖像中存在過于暗的區(qū)域或者亮度變化明顯的區(qū)域,使用全局直方圖均衡化就可能造成細節(jié)的丟失。
如果有噪聲的話,噪聲會被放大。為了避免這種情況的出現(xiàn)要使用對比度限制。
對于每個小塊來說,如果直方圖中的bin超過對比度的上限的話,就把其中的像素點均勻分散到其他bins中,然后在進行直方圖均衡化。文章來源:http://www.zghlxwxcb.cn/news/detail-812030.html
cv2.createCLAHE(clipLimit, tileGridSize)
- clipLimit:對比度限制的閾值。
- tileGridSize:用于直方圖均衡化的網(wǎng)格大小。
- clipLimit: 控制對比度的限制,它決定了對比度增強的程度。較大的值會導(dǎo)致更強烈的對比度增強。
- tileGridSize: 定義了圖像被分割成的小塊的大小。這些小塊將分別進行直方圖均衡化,以避免在整個圖像上過度增強對比度。更大的塊大小意味著更大范圍內(nèi)的對比度增強。
防止均衡化過大,對比度限制,分散到其他像素點上
# 自適應(yīng)均衡化
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread("img1/test_img.jpg", 0)
# 均衡化
clahe = cv.createCLAHE(clipLimit=1.0, tileGridSize=(8, 8))
dst = clahe.apply(img1)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(15, 12), dpi=100)
axes[0, 0].imshow(img1, cmap=plt.cm.gray)
axes[0, 0].set_title("Original")
axes[0, 1].hist(img1.ravel(), 256, [0, 256])
axes[1, 0].imshow(dst, cmap=plt.cm.gray)
axes[1, 0].set_title("Histogram Equalization")
axes[1, 1].hist(dst.ravel(), 256, [0, 256])
axes[1, 1].set_title("Histogram")
plt.show()
cv2.createCLAHE函數(shù)用于創(chuàng)建對比度受限自適應(yīng)直方圖均衡化器,它可以限制每個像素的對比度增強,以避免過度增強噪聲。
cv2.equalizeHist函數(shù)用于應(yīng)用全局直方圖均衡化,它會平衡整個圖像的直方圖,增強圖像的對比度。
因此,cv.createCLAHE可以更好地處理局部對比度不均勻的圖像,而cv2.equalizeHist適用于全局對比度增強。文章來源地址http://www.zghlxwxcb.cn/news/detail-812030.html
到了這里,關(guān)于我在Vscode學(xué)OpenCV 圖像處理五(直方圖處理)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!