九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
OpenCV機器視覺詳解之圖像匹配、直方圖、圖像均衡化

(1)模板匹配: cv2.matchTemplate();(2)圖像直方圖: cv2.calcHist();(3)圖像均衡化: cv2.equalizeHist();(4)自適應(yīng)均衡化: cv2.createCLAHE()


1. 模板匹配

模板匹配和卷積的原理很像,模板在原圖像上從原點開始滑動(從左到右, 從上到下),計算模板與(圖像被模板覆蓋的地方)的差別程度,在opencv中計算差別程度有6種計算方法。然后將每次計算結(jié)果放入一個矩陣里,作為輸出結(jié)果。假如原圖形是A*B大小,而模板是a*b大小,則輸出結(jié)果的矩陣大小是(A-a+1)*(B-b+1)

匹配方法:

cv2.matchTemplate(img, templ, method)

參數(shù):

  • img: 原始圖像
  • temple: 模板圖像
  • method: 匹配度計算方法,如下:
  • cv2.TM_SQDIFF: 計算平方差,計算結(jié)果越小,越相關(guān)
  • cv2.TM_CCORR: 計算相關(guān)性,計算出來的值越大,越相關(guān)
  • cv2.TM_CCOEFF: 計算相關(guān)系數(shù),計算出的值越大,越相關(guān)
  • cv2.TM_SQDIFF_NORMED: 計算歸一化平方差,計算結(jié)果越接近0,越相關(guān)
  • cv2.TM_CCORR_NORMED: 計算歸一化相關(guān)性,計算結(jié)果越接近1,越相關(guān)
  • cv2.TM_CCOEFF_NORMED: 計算歸一化相關(guān)系數(shù),計算結(jié)果越接近1,越相關(guān)

在開始前我們先導(dǎo)入需要用的庫函和圖像,定義一個圖像顯示函數(shù),方便后續(xù)操作

import cv2import numpy as npimport matplotlib.pyplot as plt# 獲取圖片所在文件夾filepath = 'C:\\...\\opencv\\img'# 獲取文件夾中的某一張圖片,0代表轉(zhuǎn)化灰度圖img = cv2.imread(filepath+'\\team.jpg',0)# 原圖上的一塊模板template = cv2.imread(filepath+'\\face.jpg',0)# 定義繪圖函數(shù)def cv_show(name,img): cv2.imshow(name,img) # 傳入自定義圖像名,和圖像變量 cv2.waitKey(0) # 圖片不會自動消失 cv2.destroyWindow() # 手動關(guān)閉窗口# 顯示圖像cv_show('img',img)cv_show('face',template)

我們需要在第一張圖img中找到模板face的位置,并把它框出來

1.1 匹配單個對象

模板在原圖像上移動時,返回匹配度最高的一塊區(qū)域。這里使用v2.TM_SQDIFF平方差計算方法,值越小代表匹配度越高。res中保存所有的計算結(jié)果,使用cv2.minMaxLoc()函數(shù),獲取res中的最值及最值最在的坐標位置,最值坐標是指左上角坐標(x, y),根據(jù)坐標位置和模板的寬和高,可以在原圖像中畫出目標所在位置。x軸向右為正,y軸向下為正,獲得目標右下角坐標(x+w, y+h)。注意在template.shape中提取模板尺寸的時候,shape[0]保存的是高,shape[1]保存的是寬。

#(1)匹配單個對象# img代表原始圖像,template代表模板窗口,1默認為cv2.TM_SQDIFF方法res = cv2.matchTemplate(img, template, 1) # 獲取結(jié)果的最值和最值位置min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)# 最值位置是左上角的坐標位置,通過模板的寬和高可以在原圖上把模板位置畫出來h,w = template.shape  # shape值是(高,寬)# 找出右下位置bottom_loc = (min_loc[0]+w,min_loc[1]+h)# 復(fù)制一份圖像,不然畫框的時候原圖像會變draw = img.copy()# 輸入圖像畫板draw,左上坐標,右下坐標cv2.rectangle(draw,min_loc,bottom_loc,(0,0,255),2)# 繪圖plt.subplot(121)plt.imshow(res,cmap='gray')  # 計算出的每一個窗口的結(jié)果值plt.subplot(122)plt.imshow(draw,cmap='gray') # 在畫板上把目標值框出來plt.tight_layout() #自動排版

左側(cè)是res的圖像是模板和整個圖像運算后的結(jié)果,右側(cè)框出來的是匹配度最高的圖像,匹配正確

1.2 多目標匹配

設(shè)定一個閾值,只要模板和圖像運算后的結(jié)果大于這個閾值,就將這個區(qū)域框出來,不單單識別匹配度最高的,只要滿足給定的條件就行。

在這里使用cv2.TM_SQDIFF_NORMED歸一化平方差來表明匹配度,只要匹配度小于0.2,就將這個區(qū)域選出來。使用np.where()函數(shù)來獲取所有滿足閾值條件的區(qū)域的左上角坐標點,需要注意的是,獲取的坐標點loc中依次保存的是高和寬,即(y, x),而我們在畫矩形框的時候需要的坐標pt是(x, y),因此需要把loc的坐標順序翻轉(zhuǎn)一下。得到左上角坐標(x, y),右下角坐標(x+w, y+h)

# 導(dǎo)入灰度圖img = cv2.imread(filepath+'\\team.jpg',0) # 原圖template = cv2.imread(filepath+'\\face.jpg',0) # 從原圖上取下的一塊h,w = template.shape # 獲取模板的高和寬# 圖像匹配,使用歸一化相關(guān)系數(shù)res = cv2.matchTemplate(img,template,cv2.TM_SQDIFF_NORMED)# 設(shè)置閾值,只要計算出的歸一化平方差小于0.2就把那一塊位置找出來threshold = 0.2loc = np.where(res<threshold) #輸出滿足條件的坐標# 繪制所有的滿足匹配度的窗口# zip(*) 可理解為解壓,返回二維矩陣式。loc中l(wèi)oc[0]是高,loc[1]是寬,[::-1]表示倒序。p[0]代表寬,p[1]代表高for pt in zip(*loc[::-1]): bottom_loc = (pt[0]+w,pt[1]+h) cv2.rectangle(img,pt,bottom_loc,(0,0,255),1) # 參數(shù):圖像,左上坐標,右下坐標,線條顏色,線條粗細# 繪圖cv2.imshow('img',img)cv2.waitKey(0)

線條粗細代表匹配度,中間的可能性最大,(都是同一個人...)

2. 圖像直方圖

同樣,我們先導(dǎo)入需要的庫,和圖像文件,再定義一個圖像顯示函數(shù)

import cv2import numpy as npimport matplotlib.pyplot as plt# 獲取圖片所在文件夾filepath = 'C:\\...\\opencv\\img'# 定義繪圖函數(shù)def cv_show(name,img):    # 傳入自定義圖像名,即圖像變量    cv2.imshow(name,img)     # 圖片不會自動消失    cv2.waitKey(0)    # 手動關(guān)閉窗口    cv2.destroyWindow()

2.1 直方圖繪制

用于統(tǒng)計圖像上每個像素值出現(xiàn)的次數(shù)。

(1)方法1:使用matplot繪制直方圖

# 導(dǎo)入圖像img = cv2.imread(filepath+'\\mh.jpg',0) #0代表灰度圖 # 直方圖展示plt.hist(img.ravel(),256) #ravel將二維拉長成一維,統(tǒng)計0-255每個像素值出現(xiàn)的個數(shù)plt.show()

讀入的img是灰度圖,只有兩個維度,將它變成一維統(tǒng)計像素值出現(xiàn)個數(shù),設(shè)置range=[0,256]顧頭不顧尾,對0-255每一個像素值計數(shù)。

(2)方法2:使用cv2.calcHist()函數(shù)

cv2.calcHist(img, channels, mask, histsize, ranges)

  • img:輸入圖像的圖像格式為uint8或float32,當(dāng)傳入函數(shù)時,應(yīng)用中括號,[img]
  • channels:是用中括號來告知函數(shù)繪制圖像直方圖。如果輸入的是灰度圖,則值為[0];如果是彩圖,傳入的參數(shù)可以是[0]或[1]或[2],分別對應(yīng)BGR
  • mask:掩模圖像,統(tǒng)計整幅圖的直方圖就是None。如果畫某一部分直方圖,需要制作一個掩模圖像并使用。掩模大小和img一樣的np數(shù)組,需要的部分為255,不需要的部分為0.
  • histSize:BIN的數(shù)目。應(yīng)使用中括號,控制x軸取值區(qū)間,一般為256
  • ranges:使用中括號表示像素值范圍[0, 256]顧頭不顧尾

下面對彩圖img進行直方圖統(tǒng)計,不使用掩模,分別統(tǒng)計圖像BGR三通道上的各個像素值出現(xiàn)了多少次,使用折線圖繪制曲線。hist中保存的是每個通道每個像素值出現(xiàn)的次數(shù)。

img = cv2.imread(filepath+'\\mh.jpg')  # 以彩色圖為例color = ['b','g','r']  #分別研究三顏色通道的直方圖,用顏色區(qū)分for i,col in enumerate(color):  #enumerate遍歷數(shù)據(jù)對象,返回數(shù)據(jù)和對應(yīng)下標    # i存放color下標,col存放具體值         hist = cv2.calcHist([img], [i], None, [256], [0,256])    plt.plot(hist, color=col, label=f'{col}--channel')  # 繪制三通道上每個通道像素點出現(xiàn)的個數(shù)的折線圖    plt.xlim([0,256])plt.legend()

2.2 掩模mask操作

掩模mask的大小和原圖像大小一致。掩模中只有兩部分,0和255,一部分為白色一部分為黑色。掩模中白色部分覆蓋到的區(qū)域保留原圖,黑色部分覆蓋到的區(qū)域置為0。

如果我們讀入的圖像時一張彩圖,在構(gòu)建np數(shù)組時,需要舍棄第三個維度,即通道。保留前兩個維度img.shape[:2],掩模的size和原圖像相同。由于mask是一個數(shù)組,可以使用切片的方法將需要保留的位置變成白色255。

使用圖像按位操作方法:cv2.bitwise_and(src1, src2, mask)

src: 輸入圖像

mask:掩膜,用一副二值化圖片對另外一幅圖片進行局部的遮

分別統(tǒng)計加了掩模和沒加掩模的圖像的像素點個數(shù)來對比。

img = cv2.imread(filepath+'\\shandi.jpg',0)# 創(chuàng)建mask,由于如果img是彩圖就是三維,舍棄通道取長和寬,創(chuàng)建一個和img相同大小的maskmask = np.zeros(img.shape[:2],np.uint8) # 8位無符號整型,0-255# 使用切片方法,將maks中的一部分變成255白色mask[200:700,200:700] = 255# 在圖像上覆蓋一層掩模masked_img = cv2.bitwise_and(img,img,mask=mask)# 直方圖統(tǒng)計hist_full = cv2.calcHist([img],[0],None,[256],[0,256]) # 無掩模hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256]) # 有掩模# 繪圖plt.subplot(221),plt.imshow(img,'gray') # 原圖,繪制灰度圖,不然顏色太雜plt.subplot(222),plt.imshow(mask,'gray') # 掩模圖plt.subplot(223),plt.imshow(masked_img,'gray') # 掩模覆蓋原圖plt.subplot(224),plt.plot(hist_full,label='non-mask'),plt.plot(hist_mask,label='masked') #像素值統(tǒng)計plt.legend()plt.tight_layout()plt.show()

3. 圖像均衡化

圖像的直方圖是對圖像對比度效果上的一種處理,旨在使得圖像整體效果均勻。原始圖像由于其灰度分布可能集中在較窄的區(qū)間,造成圖像不夠清晰。通過改變圖像的直方圖,來改變圖像中各像素的灰度,用于增強局部的對比度而不影響整體的對比度。這種方法對于背景和前景都太亮或者太暗的圖像非常有用。

直方圖均衡化的基本原理:對在圖像中像素個數(shù)多的灰度值(即對畫面起主要作用的灰度值)進行展寬,而對像素個數(shù)少的灰度值(即對畫面不起主要作用的灰度值)進行歸并,從而增大對比度,使圖像清晰,達到增強的目的。

均衡化函數(shù): cv2.equalizeHist(img)

img:指需要均衡化的原圖像,灰度圖像。返回值為均衡化后的圖像。

3.1 對圖像整體進行均衡化

# 原圖像有些位置的像素值特別多,有的位置很少img = cv2.imread(filepath+'\\mh1.jpg',0) #0灰度圖plt.hist(img.ravel(),256) #0-255每一個值出現(xiàn)了多少次plt.show()# ==2== 均衡化equ = cv2.equalizeHist(img)plt.hist(equ.ravel(),256)  # 將均衡化后的圖像使用ravel()拉長成一維,計算0-255每個值出現(xiàn)的次數(shù)plt.show# ==3== 圖像展示,整體做均衡化會丟失一些細節(jié)res = np.hstack((img,equ))  # 將兩張圖組合在一起cv_show('res',res)

左圖時原始圖像的像素直方圖,右圖是均衡化后的像素直方圖

左圖為原始圖像,右圖為均衡化之后的圖像。我們看出,對整體均衡化之后會大致一下細節(jié)的丟失

3.2 自適應(yīng)均衡化

整幅圖像會被分成很多小塊,然后再對每一個小塊分別進行直方圖均衡化。缺點是:如果有噪聲的話,噪聲會被放大。為了避免這種情況的出現(xiàn)要使用對比度限制。對于每個小塊來說,如果直方圖中的bin超過對比度的上限的話,就把 其中的像素點均勻分散到其他 bins中,然后在進行直方圖均衡化。

cv.createCLAHE(clipLimit, tileGridSize)

clipLimit: 顏色對比度限制,默認是40

tileGridSize: 進行像素均衡化的網(wǎng)格大小,默認為8*8

img = cv2.imread(filepath+'\\mh1.jpg',0)# 設(shè)置均衡化參數(shù),對比度閾值為2,網(wǎng)格為3*3clahe = cv2.createCLAHE(clipLimit=2,tileGridSize=(3,3))# 生成自適應(yīng)均衡化后的圖像res_clahe = clahe.apply(img)# 將三張圖象組合在一起看一下區(qū)別res = np.hstack((img,equ,res_clahe))cv_show('res',res)

第一張是原圖,第二張是整體均衡化之后的圖像,第三張是自適應(yīng)均衡化之后的圖像

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
OpenCV實戰(zhàn)(1)
改變灰度圖像直方圖的均值和標準差
使用OpenCV進行對象檢測
python+opencv圖像處理(十四)
【CV】基于閾值處理的圖像分割算法!
大家都在問
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服