12-直方圖


灰度直方圖
灰度直方圖是表示圖像中灰度值分布的直方圖,標繪了圖像中每個灰度值的像素數
橫坐標:圖像中各個像素點的灰度級
縱坐標:具有該灰度級的像素個數

歸一化直方圖
歸一化直方圖是表示圖像中灰度值分布的概率之和等於1
橫坐標:圖像中各個像素點的灰度級
縱坐標:出現這個灰度級的概率

需要注意的,直方圖術語:
dims:需要統計的特征的數目。當dims=1時,表示我們僅統計灰度值
bins:每個特征空間子區段的數目
range:每個特征空間的取值范圍

使用python中matplotlib庫來繪制直方圖
import matplotlib.pyplot as plt
函數hist(數據源,像素級),根據數據源和像素級繪制直方圖
其中,數據源必須是一維數組圖像;像素級一般是256,指[0,255]
通過ravel()函數,將多維的數組,轉化為一維的形式

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.jpg",cv2.IMREAD_COLOR)
# 彩色圖像轉化為灰度圖
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# ravel()函數,將二維的圖像,轉化為一維的數組
img_2 = img.ravel()

cv2.imshow("original",img)

# 1.設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.繪制灰度直方圖
plt.hist(img_2,256)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("灰度直方圖")
# 3.顯示灰度直方圖
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

使用opencv來繪制統計直方圖
hist = cv2.calcHist(images,channels,mask,histSize,ranges[,accumulate])
返回的hist直方圖,相當於縱坐標的值,也就是具有灰度級像素個數的二維數組
1>channels:指定通道
通道的編號需要用中括號括起來,當輸入圖像是灰度圖時,對應的通道是[0];當輸入圖像是彩色圖像時,通道[0],[1],[2]分別對應B,G,R
2>mask:掩碼圖像
統計整幅圖像的直方圖,設為None;統計圖像某一部分的直方圖時,需要掩碼圖像
3>histSize:BINS的數量
每個特征空間子區段的數目,一般是256,需要用中括號括起來
4>range:每個特征空間的取值范圍
一般是[0,255],需要用中括號括起來
5>accumulate:累計標識(可選參數)
默認值為False,如果被設置為True,則直方圖在開始分配時不會被清零。也就是說計算一組圖像的直方圖

import cv2
import numpy as np

# 輸入圖像是灰度圖
img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE)

# 繪制統計直方圖
hist = cv2.calcHist([img],[0],None,[256],[0,255])

print("統計直方圖的類型:",type(hist))
print("統計直方圖的大小:",hist.size)
print("統計直方圖的形狀:",hist.shape)

通過python的matplotlib庫,繪制opencv的統計直方圖
import matplotlib.pyplot as plt
(如果是彩色圖像,需要分別繪制BGR三個通道的直方圖)
# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import matplotlib.pyplot as plt

# 輸入圖像時彩色圖像
img = cv2.imread(r"image\girl.bmp",cv2.IMREAD_COLOR)
cv2.imshow("original",img)

# 繪制統計直方圖
histb = cv2.calcHist([img],[0],None,[256],[0,255])
histg = cv2.calcHist([img],[1],None,[256],[0,255])
histr = cv2.calcHist([img],[2],None,[256],[0,255])

# 1.設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.繪制灰度直方圖
plt.plot(histb,color="b")
plt.plot(histg,color="g")
plt.plot(histr,color="r")
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("統計直方圖")
# 3.顯示灰度直方圖
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

使用掩膜mask的直方圖
圖像掩模一般用來對處理的圖像(全部或者局部)進行遮擋,來控制圖像處理的區域或處理過程

生成掩膜mask圖像,一般需要兩步:
1> mask = np.zeros(image.shape,np.uint8)
第一步,建立與原圖一樣大小的mask圖像,並將所有像素初始化為0,也就是一張全黑色的圖
2> mask[200:400,200:400] = 255
第二步,將mask圖中指定區域的所有像素值設置為255,也就是將整個指定區域變成了白色

 

還是使用opencv來繪制統計直方圖
hist = cv2.calcHist(images,channels,mask,histSize,ranges[,accumulate])

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE)
cv2.imshow("original",img)

# 生成掩膜mask圖像
mask = np.zeros(img.shape,np.uint8)
mask[200:400,200:400] = 255
cv2.imshow("mask",mask)

# 繪制統計直方圖
hist = cv2.calcHist([img],[0],mask,[256],[0,255])

# 1.設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.繪制灰度直方圖
plt.plot(hist)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("統計直方圖")
# 3.顯示灰度直方圖
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

 直方圖均衡化
直方圖均衡化是一種簡單有效的圖像增強技術,將圖像的直方圖分布變成近似均勻分布,從而增強圖像的對比度,使色彩細節更豐富,多用於車牌識別、人臉識別場景

直方圖均衡化的過程:
1> 計算累計直方圖
2> 將累計直方圖進行區間轉換

 

 

使用opencv繪制直方圖均衡化
dst = cv2.equalizeHist(src)
其中,src是源圖像,dst是目標圖像(處理結果)

import cv2
import numpy as np
import matplotlib.pyplot as plt 

img = cv2.imread(r"image\equ.bmp",cv2.IMREAD_GRAYSCALE)

# 設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 繪制灰度直方圖
# ravel()函數,將二維的圖像,轉化為一維的數組
plt.hist(img.ravel(),256)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("灰度直方圖")

# 繪制均衡直方圖
# plt.figure()函數,創建自定義圖像
plt.figure()
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("均衡直方圖")
# 3.顯示灰度直方圖
plt.show()

cv2.imshow("original",img)
cv2.imshow("result",equ)

cv2.waitKey(0)
cv2.destroyAllWindows()

需要注意:也可以通過plt.subplot()函數,繪制多個子窗口
import matplotlib.pyplot as plt
plt.subplot(nrows,ncols,plot_number)
其中,nrows是行數,ncols是列數,plot_number是窗口序號

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt 

img = cv2.imread(r"image\equ.bmp",cv2.IMREAD_GRAYSCALE)

# 設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 通過plt.subplot()繪制一個一行兩列的子窗口
# 1.繪制灰度直方圖
plt.subplot(1,2,1)
plt.hist(img.ravel(),256)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("灰度直方圖")

# 2.繪制均衡直方圖
plt.subplot(1,2,2)
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.xlabel("灰度級")
plt.ylabel("像素個數")
plt.title("均衡直方圖")
# 3.顯示灰度直方圖
plt.show()

需要注意:也可以通過plt.imshow()函數,顯示opencv讀入的圖像
import matplotlib.pyplot as plt
plt.imshow(x,cmap)
其中,x是要繪制的圖像,cmap是顏色圖譜

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt 

# 讀取一個彩色圖像
img = cv2.imread(r"image\girl.bmp",cv2.IMREAD_COLOR)
# 彩色圖像轉換灰度圖像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 設置rc參數顯示中文標題,設置字體為SimHei顯示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 通過plt.subplot()繪制一個一行兩列的子窗口
# 1.顯示彩色圖像
plt.subplot(1,2,1)
# 拆分通道
b,g,r = cv2.split(img)
# 合並通道
rgb_img = cv2.merge([r,g,b])
plt.imshow(rgb_img)
plt.title("彩色圖像")
# 關閉坐標軸
plt.axis("off")

# 2.顯示灰度圖像
plt.subplot(1,2,2)
plt.imshow(img_gray,cmap=plt.cm.gray)
plt.title("灰度圖像")
# 關閉坐標軸
plt.axis("off")

# 3.顯示灰度直方圖
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM