基礎(chǔ)版?zhèn)魉烷T:
python3+opencv學(xué)習(xí)筆記匯總目錄(適合基礎(chǔ)入門學(xué)習(xí))
進(jìn)階版筆記目錄鏈接:
python+opencv進(jìn)階版學(xué)習(xí)筆記目錄(適合有一定基礎(chǔ))
直方圖基礎(chǔ)講解:
opencv學(xué)習(xí)筆記21:直方圖和掩膜 原理及其應(yīng)用
圖像直方圖
numpy實(shí)現(xiàn)
函數(shù):hist(數(shù)據(jù)源,像素級(jí))
數(shù)據(jù)源:圖像,必須是一維數(shù)組
像素級(jí):一般是256,指[0-255]
np.raval()可以實(shí)現(xiàn)多維數(shù)組轉(zhuǎn)一維。
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def plot_demo(image
):plt
.hist
(image
.ravel
(),256,[0,256])plt
.show
()
print("--------- Hello Python ---------")
src
= cv
.imread
("fangye.jpg")
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src
)plot_demo
(src
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
OpenCV實(shí)現(xiàn)
hist=cv2.calcHist(images,channels,mask,histsize,ranges,accumulate)
hist:直方圖
images:原始圖像,格式[src],需要用中括號(hào)括起來(lái)
channels:通道,灰色直接[0],BGR對(duì)應(yīng)[0],[1],[2]
mask:掩碼圖像。如果一個(gè)圖很大,需要計(jì)算部分圖的直方圖,需要掩碼。
histsize:BINS的數(shù)量,需要用中括號(hào)括起來(lái)。一般是[256]
ranges:像素值范圍,一般[0,255]
accumulate:累積標(biāo)識(shí)。可選參數(shù)、默認(rèn)false,設(shè)為true為計(jì)算好幾幅圖的直方圖。
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def image_hist(image
):color
= ('blue', 'green', 'red')for i
, color
in enumerate(color
):hist
= cv
.calcHist
([image
], [i
], None, [256], [0, 256])plt
.plot
(hist
, color
=color
)plt
.xlim
([0, 256])plt
.show
()
print("--------- Hello Python ---------")
src
= cv
.imread
("renwu.jpg")
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src
)image_hist
(src
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
圖像來(lái)源于網(wǎng)圖。
圖像的主要特征來(lái)源于波峰。
圖像直方圖應(yīng)用
1全局直方圖均衡化
直方圖均衡化都是基于灰色圖
原理見上面提到的基礎(chǔ)鏈接
效果:使對(duì)比圖增強(qiáng)
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def equalHist_demo(image
):gray
= cv
.cvtColor
(image
, cv
.COLOR_BGR2GRAY
)dst
= cv
.equalizeHist
(gray
)cv
.imshow
("equalHist_demo", dst
)
print("--------- Hello Python ---------")
src
= cv
.imread
("renwu.jpg")
src
=cv
.resize
(src
,None,fx
=0.5,fy
=0.5)
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src
)equalHist_demo
(src
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
2局部直方圖均衡化
局部自適應(yīng)的圖像直方圖均衡化
自適應(yīng)直方圖均衡化(AHE)是用來(lái)提升圖像的對(duì)比度的一種計(jì)算機(jī)圖像處理技術(shù)。和普通的直方圖均衡算法不同,AHE算法通過(guò)計(jì)算圖像的局部直方圖,然后重新分布亮度來(lái)改變圖像對(duì)比度。因此,該算法更適合于改進(jìn)圖像的局部對(duì)比度以及獲得更多的圖像細(xì)節(jié)。
不過(guò),AHE有過(guò)度放大圖像中相同區(qū)域的噪音的問題,另外一種自適應(yīng)的直方圖均衡算法即限制對(duì)比度直方圖均衡(CLAHE)算法能有限的限制這種不利的放大。
cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))
第一個(gè)參數(shù)的意義是那一小部分的直方圖大于clipLimit的部分將被剪裁掉平均分配 給整個(gè)圖像;第二個(gè)參數(shù)的意義是 所分小區(qū)域的大小。一般的clipLimit設(shè)置的值是40,自定義的話值越大均化的效果越顯著,值越接近零,就和原圖像沒什么區(qū)別,
原理圖:
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def clahe_demo(image
):gray
= cv
.cvtColor
(image
, cv
.COLOR_BGR2GRAY
)clahe
= cv
.createCLAHE
(clipLimit
=3.0, tileGridSize
=(5, 5))dst
= clahe
.apply(gray
)cv
.imshow
("clahe_demo", dst
)
print("--------- Hello Python ---------")
src
= cv
.imread
("renwu1.jpg")
src
=cv
.resize
(src
,None,fx
=0.6,fy
=0.6)
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src
)clahe_demo
(src
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
直方圖比較
對(duì)輸入的兩張圖像計(jì)算得到直方圖H1與H2,歸一化到相同的尺度空間,然后可以通過(guò)計(jì)算H1與H2的之間的距離得到兩個(gè)直方圖的相似程度進(jìn)而比較圖像本身的相似程度。
直方圖比較函數(shù)
cv2.compareHist(H1, H2, method)
其中:
H1,H2 分別為要比較圖像的直方圖
method - 比較方式
比較方式(method)
相關(guān)性比較 (method=cv.HISTCMP_CORREL) 值越大,相關(guān)度越高,最大值 為1,最小值為0
卡方比較(method=cv.HISTCMP_CHISQR 值越小,相關(guān)度越高,最大值無(wú)上界,最小值0
巴氏距離比較(method=cv.HISTCMP_BHATTACHARYYA) 值越小,相關(guān)度越高,最大值為1,最小值為0
import cv2
as cv
import numpy
as np
def create_rgb_hist(image
):h
, w
, c
= image
.shapergbHist
= np
.zeros
([16*16*16, 1], np
.float32
)bsize
= 256 / 16for row
in range(h
):for col
in range(w
):b
= image
[row
, col
, 0]g
= image
[row
, col
, 1]r
= image
[row
, col
, 2]index
= np
.int(b
/bsize
)*16*16 + np
.int(g
/bsize
)*16 + np
.int(r
/bsize
)rgbHist
[np
.int(index
), 0] = rgbHist
[np
.int(index
), 0] + 1return rgbHist
def hist_compare(image1
, image2
):hist1
= create_rgb_hist
(image1
)hist2
= create_rgb_hist
(image2
)match1
= cv
.compareHist
(hist1
, hist2
, cv
.HISTCMP_BHATTACHARYYA
)match2
= cv
.compareHist
(hist1
, hist2
, cv
.HISTCMP_CORREL
)match3
= cv
.compareHist
(hist1
, hist2
, cv
.HISTCMP_CHISQR
)print("巴氏距離: %s, 相關(guān)性: %s, 卡方: %s"%(match1
, match2
, match3
))print("--------- Hello Python ---------")
src1
= cv
.imread
("renwu1.jpg")
src2
= cv
.imread
("renwu.jpg")
src1
=cv
.resize
(src1
,None,fx
=0.5,fy
=0.5)
src2
=cv
.resize
(src2
,None,fx
=0.5,fy
=0.5)
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src1
)
cv
.imshow
("image2", src2
)
hist_compare
(src1
, src2
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
輸入兩張完全一樣圖片
結(jié)果
直方圖反向投影
直方圖反向投影式通過(guò)給定的直方圖信息,在圖像找到相應(yīng)的像素分布區(qū)域,opencv提供兩種算法,一個(gè)是基于像素的,一個(gè)是基于塊的。
2D直方圖建立
直方圖是基于2D的,首先先計(jì)算2D直方圖建立。
使用函數(shù) cv2.calcHist() 來(lái)計(jì)算直方圖既簡(jiǎn)單又方便。如果要繪制顏色直方圖的話,首先需要將圖像的顏色空間從 BGR 轉(zhuǎn)換到 HSV。(記住,計(jì)算二維直方圖,要從 BGR 轉(zhuǎn)換到 HSV)。計(jì)算 2D 直方圖,函數(shù)的參數(shù)要做如下修改:
? channels=[0, 1] 因?yàn)槲覀冃枰瑫r(shí)處理 H 和 S 兩個(gè)通道。
? bins=[180, 256]H 通道為 180, S 通道為 256。 如果寫其他數(shù)值(小于180,256)則表示是通道合并。
? range=[0, 180, 0, 256]H 的取值范圍在 0 到 180, S 的取值范圍在 0 到 256。
hist = cv2.calcHist([image], [0, 1], None, [32, 32], [0, 180, 0, 256])
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def hist2d_demo(image
):hsv
= cv
.cvtColor
(image
, cv
.COLOR_BGR2HSV
)hist
= cv
.calcHist
([image
], [0, 1], None, [180, 256], [0, 180, 0, 256])plt
.imshow
(hist
, interpolation
='nearest')plt
.title
("2D Histogram")plt
.show
()
print("--------- Hello Python ---------")
src
= cv
.imread
("yangmi.jpg")
src
=cv
.resize
(src
,None,fx
=0.5,fy
=0.5)
cv
.namedWindow
("input image", cv
.WINDOW_AUTOSIZE
)
cv
.imshow
("input image", src
)
hist2d_demo
(src
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
直方圖反向投影
此段代碼有借鑒他人
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
def back_projection_demo():roi
= cv
.imread
("head.png")target
= cv
.imread
("renwu.jpg")target
= cv
.resize
(target
, None, fx
=0.2, fy
=0.2)roi_hsv
= cv
.cvtColor
(roi
, cv
.COLOR_BGR2HSV
)target_hsv
= cv
.cvtColor
(target
, cv
.COLOR_BGR2HSV
)cv
.imshow
("roi", roi
)roiHist
= cv
.calcHist
([roi_hsv
], [0, 1], None, [180,256], [0, 180, 0, 256])cv
.normalize
(roiHist
, roiHist
, 0, 255, cv
.NORM_MINMAX
)dst
= cv
.calcBackProject
([target_hsv
], [0, 1], roiHist
, [0, 180, 0, 256], 1)disc
= cv
.getStructuringElement
(cv
.MORPH_ELLIPSE
, (5, 5))dst
= cv
.filter2D
(dst
, -1, disc
)ret
, thresh
= cv
.threshold
(dst
, 200, 255, 0)thresh
= cv
.merge
((thresh
, thresh
, thresh
))res
= cv
.bitwise_and
(target
, thresh
)res
= np
.hstack
((target
, thresh
, res
))cv
.imshow
('res',res
)back_projection_demo
()
cv
.waitKey
(0)cv
.destroyAllWindows
()
原始模板ROI
即從目標(biāo)圖尋找和模板相似的區(qū)域(直方圖相似)
結(jié)果:
要修改 ret, thresh = cv.threshold(dst, 200, 255, 0) 數(shù)值才能得到更好。
電氣專業(yè)的計(jì)算機(jī)萌新,寫博文不容易。如果你覺得本文對(duì)你有用,請(qǐng)點(diǎn)個(gè)贊再走。謝謝。
總結(jié)
以上是生活随笔為你收集整理的opencv进阶学习笔记7:直方图,直方图均衡化,直方图比较,直方图反向投影的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。