本文中涉及到的 matplotlib 繪圖庫的知識可以參考我的之前的文章:Python 繪圖庫 Matplotlib
目錄
1. 直方圖概述
(1)基本概念
(2)直方圖中的術語
BINS
DIMS
RANGE
2. 直方圖繪制
(1)讀取影像資訊
(2)繪制直方圖
灰度圖的直方圖
彩色圖直方圖
3. 掩膜直方圖
(1)基本概念
(2)實作代碼
得到掩模圖
繪制掩膜直方圖
4. H-S 直方圖
(1)基本概念
(2)繪制二維H-S直方圖
結束語
1. 直方圖概述
(1)基本概念
直方圖就是對影像的另外一種解釋,它描述了整幅影像的灰度分布,直方圖的 x 軸代表灰度值(0~255),y 軸代表圖片中同一種灰度值的像素點的數目,所以通過直方圖我們可以對影像的亮度、灰度分布、對比度等有了一個直觀的認識
(2)直方圖中的術語
BINS
前面說到,直方圖中的 x 軸表示的是灰度值,一幅灰度圖的灰度等級有 256 級,所以我們是否需要將每一個等級標注在一條軸上呢?或者如果我們需要的不是每一個灰度值的分布,而是一個范圍內的灰度分布呢?所以我們將每一個需要的灰度值范圍稱為一個 BIN,即所有的灰度等級被分為幾個小組,每一個小組是一個 BIN
DIMS
代表的是我們收集的影像的引數的數目,直方圖我們如果只收集灰度值一個引數,那么該引數的值就是1
RANGE
代表統計的灰度值的范圍,一般的范圍是[0-255]
2. 直方圖繪制
(1)讀取影像資訊
在計算機視覺系列的文章中第一件事就是讀取影像資訊:
"""
Author:XiaoMa
date:2021/10/24
"""
#呼叫需要的包
import cv2
import matplotlib.pyplot as plt
img0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY) #轉化為灰度圖
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay = 0)
影像資訊如下:
419 636

(2)繪制直方圖
繪制直方圖使用的函式如下:
hist = cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
images:原圖
channels:指定通道 [0]代表灰度圖,如果讀入的影像不是灰度圖,該值可以是[0],[1],[2]分別代表通道 B,G,R
mask:掩碼影像,進行整張圖的繪制時為 None
histSize:BIN 的數量
ranges:像素值范圍
accumulate:累計標識,一般可以省略
灰度圖的直方圖
#繪制直方圖
hist = cv2.calcHist([img1], [0], None, [256], [0, 255])
plt.plot(hist, color = 'lime', label = '直方圖', linestyle = '--')
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')
plt.show()
可以看出這幅灰度圖中亮度較高的像素點還是占多數的,即整體亮度較高
彩色圖直方圖
讀入彩色影像,并對某一個通道進行直方圖繪制
"""
Author:XiaoMa
date:2021/10/24
"""
#呼叫需要的包
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei' #將全域中文字體改為黑體
img0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img0)
cv2.waitKey(delay = 0)
#繪制直方圖
hist = cv2.calcHist([img0], [0], None, [256], [0, 255])
plt.plot(hist, color = 'lime', label = '藍色通道直方圖', linestyle = '--', alpha = 1)
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')
plt.show()

上圖就是對藍色通道繪制的直方圖
3. 掩膜直方圖
(1)基本概念
如果我們不需要整幅影像中的直方圖,而是某個區域的直方圖,我們只需要繪制一幅圖,將需要統計的部分設定為白色,不需要統計的部分設定為黑色,就構成了一幅掩膜影像
(2)實作代碼
得到掩模圖
##得到掩膜圖
mask = np.zeros(img0.shape, np.uint8) #將每一個像素點設定為0,就是黑色
mask[109:309, 212:412] = 255 #選取特定區域設定為白色
img0_1 = cv2.bitwise_and(img0, mask) #影像與操作得到掩膜圖
cv2.namedWindow("W1")
cv2.imshow("W1", img0_1)
cv2.waitKey(delay = 0)

繪制掩膜直方圖
#繪制掩膜直方圖
##得到掩膜圖
mask = np.zeros(img1.shape, np.uint8) #將每一個像素點設定為0,就是黑色
mask[109:309, 212:412] = 255 #選取特定區域設定為白色
img1_1 = cv2.bitwise_and(img1, mask) #影像與操作得到掩膜圖
cv2.namedWindow("W1")
cv2.imshow("W1", img1_1)
cv2.waitKey(delay = 0)
##繪制掩膜直方圖和部分影像直方圖
hist1 = cv2.calcHist([img1], [0], mask, [256], [0, 255]) #掩膜圖直方圖,引數需要修改
hist2 = cv2.calcHist([img1], [0], None, [256], [0,255])
plt.plot(hist1, color = 'b', label = '掩膜直方圖', linestyle = '--')
plt.plot(hist2, color = 'r', label = '原圖直方圖', linestyle = '-.')
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven2.jpeg')
plt.show()
得到的影像如下:
4. H-S 直方圖
(1)基本概念
H(Hue) - S(Saturation) 直方圖,即色調 - 飽和度直方圖
繪制該直方圖需要將源RGB影像轉化到 HSV (色調、飽和度、亮度)顏色空間中去
對于HSV空間的介紹可以參考:影像處理(HSV)
img0_2 = cv2.cvtColor(img0, cv2.COLOR_BGR2HSV) #將 RGB 空間轉化為 HSV 空間
cv2.namedWindow("W2")
cv2.imshow("W2", img0_2)
cv2.waitKey(delay = 0)
(2)繪制二維H-S直方圖
此處參考:OpenCV 官網
##繪制H-S直方圖
hist3 = cv2.calcHist ([img0_2], [0, 1], None , [180, 256], [0, 180, 0, 256])#官網給出的解釋:channel = [0,1] 因為我們需要同時處理 H 和 S 平面;bins = [180,256] H 平面為 180,S 平面為 256;range = [0,180,0,256] 色調值介于 0 和 180 之間,飽和度介于 0 和 256 之間
plt.imshow(hist3)
plt.savefig('E:\From Zhihu\For the desk\cvseven3.jpeg')
plt.show()
得到的影像如下:

上圖中的 X 軸代表S(飽和度),Y軸代表H(色調)
該圖中的峰值主要分布在 S 在(0-50)之間 H在(20-80),至于為什么峰值較少,個人猜測是由于原圖中的色彩變化不明顯,導致沒辦法繪制出過多過明顯的峰值
結束語
本篇文章簡單介紹了影像直方圖的概念,并進行了直方圖、掩膜直方圖、H-S 直方圖的繪制,參考的一些文章都添加在了原文中,如果需要深入了解可以點進去進行學習,加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335337.html
標籤:其他
上一篇:小白同學高效入門目標檢測之YOLO實戰系列精選 | 【??1024專刊??】
下一篇:目標檢測----YOLOV1
