天天看點

opencv中直方圖操作直方圖

直方圖

1 灰階直方圖

1.1 原理

直方圖是對資料進行統計的一種方法,并且将統計值組織到一系列實作定義好的 bin 當中。其中, bin為直方圖中經常用到的一個概念,可以譯為“直條”或“組距”,其數值是從資料中計算出的特征統計量,這些資料可以是諸如梯度、方向、色彩或任何其他特征。

圖像直方圖(Image Histogram)是用以表示數字圖像中亮度分布的直方圖,标繪了圖像中每個亮度值的像素個數。這種直方圖中,橫坐标的左側為較暗的區域,而右側為較亮的區域。是以一張較暗圖檔的直方圖中的資料多集中于左側和中間部分,而整體明亮、隻有少量陰影的圖像則相反。

直方圖的一些術語和細節:

  • dims:需要統計的特征數目。
  • bins:每個特征空間子區段的數目,可譯為“直條”或“組距”。
  • range:要統計特征的取值範圍。

直方圖的意義:

  • 直方圖是圖像中像素強度分布的圖形表達方式
  • 他統計了每一個強度值所具有的像素個數
  • 不同的圖像的直方圖可能是相同的

1.2 直方圖的計算和繪制

我們使用OpenCV中的方法統計直方圖,并使用matplotlib将其繪制出來。

API:

cv.calcHist(images,channels,mask,histSize,rangs[,hist[,accumulate]])

參數:

  • images:原圖像。當傳入函數時應該用中括号[]括起來,例如:[img]。
  • channels:通道,如果輸入圖像時灰階圖,它的值就是[0];如果是彩色圖像的話,傳入的參數可以是[0],[1],[2]他們分别對應着通道B、G、R。
  • mask:掩模圖像。要統計整幅圖像的直方圖就把它設為None。但是如果你想統計圖像某一部分的直方圖的話,你就需要制作一個掩模圖像,并使用它。
  • histSize:bin的數目。也應該用中括号括起來,例如:[256]。
  • ranges:像素值範圍,通常為[0,256]。

示例:如下圖,繪制相應的直方圖

import cv2 as cv
import matplotlib.pyplot as plt

# 1 直接以灰階圖的方式讀入
img = cv.imread("../image/yy.jpg")
# 2 統計灰階圖
histr = cv.calcHist([img],[0],None,[256],[0,256])
# 3 繪制灰階圖
plt.figure(figsize=(10,6),dpi=100)
plt.plot(histr)
plt.grid()
plt.show()
           

1.3 掩膜的應用

掩膜是用標明的圖像、圖形或物體,對要處理的圖像進行遮擋,來控制圖像處理的區域。

在數字圖像進行中,我們通常使用二維矩陣數組進行掩膜。掩膜是由0和1組成一個二進制圖像,利用該掩膜圖像要處理的圖像進行掩膜,其中1值的區域被處理,0值區域被屏蔽,不會處理。

掩膜的主要用途是:

  • 提取感興趣區域:用預先制作的感興趣區掩模與待處理圖像進行"與“操作,得到感興趣區圖像,感興趣區内圖像值保持不變,而區外圖像值都為0。
  • 屏蔽作用:用掩模對圖像上某些區域作屏蔽,使其不參加處理或不參加處理參數的計算,或僅對屏蔽區作處理或統計。
  • 結構特征提取:用相似性變量或圖像比對方法檢測和提取圖像中與掩模相似的結構特征。
  • 特殊形狀圖像制作

掩膜在遙感影像進行中使用較多,當提取道路或者河流,或者房屋時,通過一個掩膜矩陣來對圖像進行像素過濾,然後将我們需要的地物或者标志突出顯示出來。

我們使用**cv.calcHist ()**來查找完整圖像的直方圖。如果要查找圖像某些區域的直方圖,該怎麼辦?隻需在要查找直方圖的區域上建立一個白色的掩膜圖像,否則建立黑色,然後将其作為掩碼mask傳遞即可。

示例:

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

# 1 灰階圖
img = cv.imread("../image/yy.jpg",0)
# 2 建立蒙版
mask = np.zeros(img.shape[:2],np.uint8)
mask[400:650,200:500] = 255
# 3 掩膜
mask_img = cv.bitwise_and(img,img,mask = mask)
# 4 統計掩膜後圖像的灰階圖
mask_histr = cv.calcHist([img],[0],mask,[256],[1,256])
# 5 圖像顯示
fig,axes = plt.subplots(nrows=2,ncols=2,figsize=(15,12))
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("蒙版資料")
axes[1,0].imshow(mask_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()
           

2 直方圖均衡化

2.1 原理與應用

“直方圖均衡化"是把原始圖像的灰階直方圖從比較集中的某個灰階區間變成在更廣泛灰階範圍内的分布。直方圖均衡化就是對圖像進行非線性拉伸,重新配置設定圖像像素值,使一定灰階範圍内的像素數量大緻相同。

這種方法提高圖像整體的對比度,特别是有用資料的像素值分布比較接近時,在X光圖像中使用廣泛,可以提高骨架結構的顯示,另外在曝光過度或不足的圖像中可以更好的突出細節。

使用opencv進行直方圖統計時,使用的是:

API:

dst = cv.equalizeHist(img)

參數:

  • img:灰階圖像

傳回:

  • dst:均衡化後的結果

示例:

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread("../image/yy.jpg",0)  #灰階圖
dst = cv.equalizeHist(img)	#均衡化
plt.imshow(img,cmap=plt.cm.gray)  #原圖
plt.show()
plt.imshow(dst,cmap=plt.cm.gray)  #均衡化後的圖
plt.show()
           

2.2自适應的直方圖均衡化

API:

cv.createCLAHE(clipLimit,tileGridSize)

參數:

  • clipLimit:對比度限制,預設值是40
  • tileGridSize:分塊的大小,預設為8*8

示例:

import matplotlib.pyplot as plt
import cv2 as cv

img = cv.imread("../image/yy.jpg",0)
# 建立一個自适應均衡化的對象,并應用于圖像
clahe = cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
cl = clahe.apply(img)
plt.imshow(img,cmap=plt.cm.gray)  #原圖
plt.show()
plt.imshow(cl,cmap=plt.cm.gray)  #均衡化後的圖
plt.show()
           

3 總結

1.灰階直方圖:

  • 直方圖是圖像中像素強度分布的圖形表達方式
  • 它統計了每一個強度值所具有的像素個數
  • 不同的圖像的直方圖可能是相同的
  • API :cv.calcHist (images,channels,mask,histSize,ranges [,hist [, accumulate]])

2.掩膜

​ 建立蒙版,透過mask進行傳遞,可擷取感興趣區域的直方圖

3.直方圖均衡化:增強圖像對比度的一種方法

​ cv.equalizeHist():輸入是灰階圖像,輸出是直方圖均衡圖像

4.自适應的直方圖均衡

​ 将整幅圖像分成很多小塊,然後再對每一個小塊分别進行直方圖均衡化,最後進行拼接

​ API: clahe = cv.createCLAHE(clipLimit, tileGridSize)

注:以上資料來自b站黑馬程式員視訊,點選跳轉