




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
人工智能綜合項(xiàng)目開發(fā)第二章OpenCV基礎(chǔ)成都職業(yè)技術(shù)學(xué)院OpenCV簡介01OpenCV安裝02圖像讀取與顯示03視頻的讀取與顯示04圖像基本操作05OpenCV
基礎(chǔ)OpenCV
簡介OpenCV(Open
Source
Computer
Vision
Library)是一個開源的跨平臺計(jì)算機(jī)視覺
和機(jī)器學(xué)習(xí)庫。擁有超過
2500
種優(yōu)化算法,包括一套全面的、經(jīng)典的和最先進(jìn)的計(jì)算機(jī)
視覺和機(jī)器學(xué)習(xí)算法。這些算法可用于檢測和識別面部,識別物體,對視頻中的人體動
作進(jìn)行分類,跟蹤相機(jī)移動,跟蹤移動物體等應(yīng)用。OpenCV
其本身是用
C++編寫的,同時提供了
C++,Python,Java
和
MATLAB
程序接口,
并支持
Windows、Linux、Android、Mac
OS
等操作系統(tǒng)。如圖
0-1
所示,1999
年
Intel
公司為增強(qiáng)
CPU
集群性能,啟動了很多研究項(xiàng)目,其
中就包括
OpenCV。OpenCV
最初的核心代碼和算法規(guī)范是英特爾實(shí)驗(yàn)室團(tuán)隊(duì)完成的。2018
年發(fā)布了
OpenCV4.X
版本,該版本全面加強(qiáng)了算法的性能,補(bǔ)充了神經(jīng)網(wǎng)絡(luò)等模塊功能。圖
0-1OpenCV
版本迭代歷史OpenCV
安裝Python
開發(fā)環(huán)境安裝
OpenCV
依賴包可使用如下命令安裝。pip3
instal
opencv-python
-i
/simple
--user使用
pip3,意思是在
python3
中安裝
opencv-python
庫,可以使用如下命令來查看
pip3
的版本號和
pip3
所對應(yīng)的庫安裝路徑。-i
選項(xiàng)指定倉庫源,這使用豆瓣提供的
pip
源,用來加速下載。--user
選項(xiàng)指定是用戶安裝,避免出現(xiàn)權(quán)限不足的問題,而入致安裝失敗。pi@raspberrypi:~$
pip3
--versionpip
19.3.1
from
/usr/local/lib/python3.7/dist-packages/pip
(python
3.7)任注意
如果需要安裝指定版本的
opencv-python
庫。可以使用如下命令先查詢當(dāng)前有多少版本可供安裝。pip3
install
opencv-python==報(bào)錯,然后提示可以從如下版本中選擇安裝。ERROR:
Could
not
find
a
version
that
satisfies
the
requirement
opencv-python==
(from
versions:
,
,
,
,
,
,
,
,
,
,
0,1,
2,
4,
5,
6,
7,
8,
9,
0,
7,
8,
9,
1,
3,
4,
5,
6,
0)比如,需要安裝
opencv-python
庫的
6
版本,則安裝命令如下:pip3
instal
opencv-python==6
-i
https:///simple
--user圖像讀取與顯示讀入、顯示和保存圖像和視頻數(shù)據(jù)是計(jì)算機(jī)視覺中最基本也是必不可少的操作,OpenCV
提供了這些基礎(chǔ)操作的
API
函數(shù),通過本節(jié)內(nèi)容,開發(fā)者可以掌握如何使用OpenCV
庫中的函數(shù)進(jìn)行圖像和視頻的讀取、顯示和存儲。使用
OpenCV
庫的
imread
函數(shù)實(shí)現(xiàn)從磁盤中讀取一張圖像,使用函數(shù)
imshow
將它顯
示到
GUI
窗口中,圖像寫入使用
imwrite
函數(shù)。讀取、顯示與寫入圖像的流程如圖
0-1
所示:圖
0-1
圖像讀取顯示與寫入基本流程根據(jù)圖
4-2
流程,讀取一張圖片并顯示的示例代碼如下:import
cv2
as
cv#
自定義圖片地址
img_path
=
'./test_alpha.png'
#
讀入圖像img_bgr
=
cv.imread(img_path)
#
顯示圖片
cv.imshow('img_bgr',
img_bgr)
#
無限期的等待鍵盤按下
cv.waitKey(0)#銷毀所有窗體
cv.destroyAllWindows()#
存儲圖片,將圖片保存成
jpg
格式
cv.imwrite('./test.jpg',
img_bgr)通過上述代碼,可以將.png
格式的圖片另存為.jpg
格式的圖像,這是因?yàn)楹瘮?shù)
imwrite()會根據(jù)文件名的后綴名來選擇不同的壓縮編碼方式,開發(fā)者只需更改文件后綴
名即可實(shí)現(xiàn)將圖像保存成不同的圖像格式。視頻的讀取與顯示OpenCV
為開發(fā)者提供了
CV2.VideoCapture
視頻捕獲類函數(shù),這是一個通用的捕獲視頻圖像的程序接口。CV2.VideoCapture
視頻捕獲類函數(shù)如下表
4-1
所示:表
4-1
攝像頭捕獲構(gòu)造類功能cv2.VideoCapture
類的構(gòu)造函數(shù)參數(shù)說明視頻文件<VideoCaputrue
object>
=
cv2.VideoCapture(VideoPath)VideoPath:本地視頻文件路徑攝
像
頭
設(shè)
備<VideoCaputrue
object>
=
cv2.VideoCapture(index)index:攝像頭設(shè)備
ID,填
0
表示
使用系統(tǒng)默認(rèn)的攝像頭,在
linux
系統(tǒng)中,如果存在多個攝像頭,可
以使用“/dev/video1“
等這樣的
設(shè)備名通過構(gòu)造函數(shù)可獲得
VideoCapture
類的實(shí)例對象,通過實(shí)例對象
VideoCapture
的成
員方法
read
讀取視頻幀。使用
OpenCV
捕獲視頻流非常容易,流程如下圖
0-1
所示:圖
0-1
視頻捕獲基本流程視頻流捕獲示例代碼如下:import
cv2
as
cv#獲取本地?cái)z像頭對象
cap
=
cv.VideoCapture(0)
#如果檢測到攝像頭已打開
if
cap.isOpened():state,
frame
=
cap.read()
#抓取下一個視頻幀狀態(tài)和圖像while
state:#當(dāng)抓取成功則進(jìn)入循環(huán)state,frame
=
cap.read()
#
抓取每一幀圖像cv.imshow('video',frame)
#
顯示抓取到的圖像幀#
等待鍵盤按下,超時
25ms
可通過設(shè)置等待超時時間來控制視頻播放速度。k
=
cv.waitKey(25)
&
0xff
#
25ms
內(nèi)當(dāng)有鍵盤按下時返回對應(yīng)按鍵
ASCII
碼,超時返回-1if
k
==
27
or
chr(k)
==
‘q’:
#
當(dāng)按下
Esc
或者
q
時退出循環(huán)。break(1)視頻存儲視頻是由一幀一幀的圖像構(gòu)成的,當(dāng)一秒中內(nèi)切換
24
幀圖像,人眼就會覺得視頻流暢,人們把一秒鐘切換圖像的次數(shù)叫做幀率(FPS),如一秒鐘能切換
30
張圖像,則其幀率為
30FPS。為了減少視頻大小,設(shè)計(jì)了很多視頻壓縮編碼格式,如常見的
MPEG-4、H.264、H.265。將視頻壓縮編碼之后,原來為
4.976
GB
的視頻文件就被壓縮到
50MB
以內(nèi),且畫質(zhì)還原度高。在
OpenCV
中的
VideoWriter
類提供的
API
可以輕松實(shí)現(xiàn)視頻編碼壓縮。目前視頻信
息壓縮編碼的方法很多,fourcc
是用于設(shè)置壓縮幀的
4
字符編解碼方式代碼。視頻保存示例代碼如下:#!/usr/bin/env
python3
#
-*-
coding:UTF8
-*-
import
cv2
as
cv
import
numpy
as
np#獲取本地?cái)z像頭對象
cap
=
cv.VideoCapture(0)#
指定視頻的編碼格式fourcc
=
cv.VideoWriter_fourcc(*
'XVID')
#
保存到文件,VideWriter
參數(shù)說明:#
VideWriter(文件名,
編碼格式,
FPS,
幀大小,isColor),isColor
默認(rèn)為
True
表示保存彩圖
out
=
cv.VideoWriter('output.avi',
fourcc,
30,
(640,
480))while
cap.isOpened():
ret,
frame
=
cap.read()
if
ret:#
幀翻轉(zhuǎn)
圖像基本操作圖像運(yùn)算指以圖像為單位進(jìn)行的操作,該操作對圖像中的所有像素同樣進(jìn)行,運(yùn)算
的結(jié)果是一幅其灰度分布與原來參與運(yùn)算圖像灰度分布不同的新圖像。具體的運(yùn)算主要
包括算術(shù)和邏輯運(yùn)算,它們通過改變像素的值來得到圖像增強(qiáng)的效果。算術(shù)運(yùn)算是指對兩幅或兩幅以上的輸入圖像中對應(yīng)像素的灰度值作加、減、乘或除
等運(yùn)算后,將運(yùn)算結(jié)果作為輸出圖像相應(yīng)像素的灰度值。這種運(yùn)算的特點(diǎn)在于:其一,
輸出圖像像素的灰度僅取決于兩幅或兩幅以上的輸入圖像的對應(yīng)像素灰度值,和點(diǎn)運(yùn)算out.write(frame)
#
保存視頻幀cv.imshow('frame',
frame)
#
顯示當(dāng)前幀k
=
cv.waitKey(25)
&
0xFFif
chr(k)
==
'q':
#
按‘q’鍵退出break#
調(diào)用
release
函數(shù)釋放內(nèi)存cap.release()out.release()cv.destroyAllWindows()相似,算術(shù)運(yùn)算結(jié)果和參與運(yùn)算像素的鄰域內(nèi)像素的灰度值無關(guān);其二,算術(shù)運(yùn)算不會
改變像素的空間位置。(1)圖像按位運(yùn)算圖像的基本運(yùn)算有很多種,比如兩幅圖像可以相加、相減、相乘、相除、位運(yùn)算、
平方根、對數(shù)、絕對值等。通常在圖像處理過程中需要對圖像截取其中的一部分作為感
興趣的區(qū)域(region
of
interest,ROI),按位運(yùn)算常被廣泛用于
ROI
區(qū)域提取。所謂按位運(yùn)算,就是對圖像像素的二進(jìn)制形式的每個
bit
進(jìn)行對應(yīng)運(yùn)算。按位運(yùn)算
通常包括按位與、按位或、按位非和按位異或運(yùn)算。OpenCV
提供了函數(shù)
cv2.
bitwise_and
能將兩幅圖像
src1
與
src2
每個像素值進(jìn)行位
與運(yùn)算,并返回處理后的圖像。該函數(shù)的用法如表
5-1
所示:表
5-1
位與函數(shù)函數(shù)名稱cv2.bitwise_and函數(shù)原型bitwise_and(src1,
src2[,
dst[,
mask]])
->
dst必填參數(shù)src1&src2:輸入的需要按位與的圖像,要求兩幅圖像有相同的類型和大小默認(rèn)參數(shù)dst:與輸入圖像有同樣大小和類型的輸出圖像mask:輸入掩模,可省略參數(shù),必須是
8
位單通道圖像返回值返回位與之后的圖像調(diào)用示例output
=
cv2.bitwise_and(source,
mask)函數(shù)
cv2.bitwise_not
將輸入圖像
src
每個像素值按位取反,并返回處理后的圖像。
該函數(shù)的用法如表
5-2
所示:表
5-2
位或函數(shù)函數(shù)名稱cv2.
bitwise_not函數(shù)原型bitwise_not(src[,
dst[,
mask]])
->
dst必填參數(shù)src:輸入的需要按位取反的圖像默認(rèn)參數(shù)dst:與輸入圖像有同樣大小和類型的輸出圖像mask:輸入掩模,可省略參數(shù),必須是
8
位單通道圖像返回值返回位與之后的圖像調(diào)用示例output
=
cv2.bitwise_not(source)(2)圖像加法OpenCV
提供了
cv2.add()函數(shù)實(shí)現(xiàn)圖像相加,使用該函數(shù)進(jìn)行圖像的加法運(yùn)算時,
相加的兩張圖像應(yīng)保證
shape
一致。此外圖像的加法運(yùn)算還可以通過
Numpy
實(shí)現(xiàn),不同的)是
OpenCV
的加法是一種飽和操作,而
Numpy
中的加法是一種模操作,如下面代碼所示:
圖像加法函數(shù)中
cv2.addWeighted()函數(shù)能做圖像混合,函數(shù)的計(jì)算公式如下:
(
)
=
(
0(
)
1(
)
+因?yàn)閮煞鶊D片相加的權(quán)重不同,所以有混合的效果,通過修改
α
的值(0→1)便可
以實(shí)現(xiàn)非常好的混合效果,參考代碼如下所示:數(shù)字圖像顏色空間數(shù)字圖像中的灰度圖每一個像素都是由一個數(shù)字量化的,而彩色圖像的每一個像素
都是由至少三個數(shù)字進(jìn)行量化,因此顏色空間的用途是保證在一個固定的標(biāo)準(zhǔn)下能夠?qū)?/p>
某一種顏色加以說明量化。針對不同數(shù)字成像系統(tǒng)和領(lǐng)域各自的特點(diǎn),目前已經(jīng)存在上x=np.uint8([250])y=np.uint8([10])print(cv2.add(x,y)
#
OpenCV
實(shí)現(xiàn)圖像相加[[255]]
#
250+10=260=>255print(x+y)
#
Numpy
實(shí)現(xiàn)圖像相加[[4]]
#
250+10=260%256=4img=cv2.addWeighted(img1,
0.7,
img2,
0.3,
0)百種對彩色圖像色彩的量化方式,比較常用的三色顏色空間包括
RGB、HSV、Lab、YUV
等。RGB
色彩空間源于使用陰極射線管的彩色電視,是人們接觸最多的顏色空間之一。
RGB
分別代表三個基色(R-紅色、G-綠色、B-藍(lán)色),具體的色彩值由三個基色疊加而成。
在圖像處理中,常使用向量表示色彩的值,如(0,0,0)表示黑色、(255,
255,
255)
表示白色,其中,255
表示色彩空間被量化成
255
個數(shù),最高亮度值為
255。在這個色彩
空間中,有
256*256*256
種顏色,因此
RGB
色彩空間是一個包含
Red、Green、Blue
的三
維空間。HSV(Hue-色調(diào)、Saturation-飽和度、Value-值)色彩空間將亮度從色彩中分解出
來,由于其對光線不敏感的特性,在圖像增強(qiáng)算法中用途很廣。在圖像處理中,經(jīng)常將
圖像從
RGB
色彩空間轉(zhuǎn)換到了
HSV
色彩空間,利用
HSV
分量從圖像中提取
ROI
區(qū)域,以便
更好地感知圖像顏色。由于在圖像處理過程中,HSV
模型比
RGB
模型更適合做預(yù)處理,且日常生活中的顯示設(shè)備大多都是使用
RGB
顏色空間,因此常需將兩個顏色空間進(jìn)行互換。OpenCV
中實(shí)現(xiàn)了顏色空間轉(zhuǎn)換的接口函數(shù)
cv2.cvtColor(),函數(shù)參數(shù)說明如表
5-3
所示:表
5-3
顏色空間轉(zhuǎn)換函數(shù)函數(shù)名稱cv2.cvtColor函數(shù)原型cvtColor(src,
code[,
dst[,
dstCn]])
->
dst必填參數(shù)src:輸入圖像code:顏色空間轉(zhuǎn)換類型,常用的是:
cv2.COLOR_BGR2HSV
cv2.COLOR_HSV2BGR
cv2.COLOR_BGR2GRAY
cv2.COLOR_GRAY2BGR默認(rèn)參數(shù)dstCn:輸出圖像的顏色通道數(shù),默認(rèn)為
0,此時輸出圖像通道數(shù)將由
code
決定返回值轉(zhuǎn)換了顏色空間后的圖像調(diào)用示例hsv
=
cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
bgr
=
cv2.cvtColor(img,cv2.COLOR_HSV2BGR)(1)圖像通道拆分及合并如果對圖像的單個通道進(jìn)行特殊操作,需要把
BGR
拆分成三個單獨(dú)的通道,操作完單個通道后,再將三個單獨(dú)的通道合并成一張
BGR
圖,如下所示為通道拆分及合并操作
示例:
使用
cv2.split()分割通道,cv2.merge()合并通道,這是一種有很大開銷的操作,
因此實(shí)際開發(fā)中建議使用如下代碼替代:
(2)顏色閾值分割在做顏色識別時,常需單獨(dú)提取出某一種顏色來做一些識別操作,這時候需要檢查
圖片元素是否在顏色高低閾值之間。OpenCV
中提供了
cv2.inRange()函數(shù)進(jìn)行閾值分割,
這個函數(shù)根據(jù)上下顏色邊界閾值對原輸入圖像進(jìn)行分割,上下閾值之外的像素全部設(shè)置b,g,r=cv2.split(img)img=cv2.merge((b,g,r))#
使用
python
切片來完成通道分割和替換功能b=img[:,:,:1]g=img[:,:,1:2]r=img[:,:,2:3]img[:,:,2:3]=rimg[:,:,1:2]=gimg[:,:,0:1]=b為
0,閾值之間的像素值設(shè)置為全
1,返回的是一個二值圖,即掩模。cv2.inRange()函數(shù)參數(shù)說明如表
5-4
所示:表
5-4
inRange
函數(shù)函數(shù)名稱cv2.inRange函數(shù)原型inRange(src,
lowerb,
upperb[,
dst])
->
dst必填參數(shù)src:輸入圖像lowerb:設(shè)置分割的下邊界閾值upperb:設(shè)置分割的上邊界閾值返回值返回顏色提取后的二值圖像,即掩模。調(diào)用示例mask=
cv2.inRange(hsv,
(0,
43,
46),
(10,
255,
255))因此,常使用
inRange
進(jìn)行閾值處理操作,能達(dá)到分割指定顏色塊的目的。將圖像
轉(zhuǎn)化到
HSV
顏色空間下,然后參照表
5-5
所示
HSV
顏色空間對照表,即可根據(jù)顏色空間值
分割出指定顏色塊。表
5-5
HSV
顏色空間對照表黑灰白紅橙黃綠青藍(lán)紫hmin0000
15611263578100125hma/p>
18025347799124155smin00043434343434343smax2554330255255255255255255255vmin04622146464646464646vmax46220255255255255255255255255以分割綠色圖像為例,首先使用
inRange()函數(shù)來進(jìn)行分割然后與原圖進(jìn)行位與運(yùn)算實(shí)現(xiàn)綠色分割,示例代碼如下所示:import
cv2
as
cv#
1)載入圖像img_src
=
cv.imread('rub00.jpg')#
2)轉(zhuǎn)換空間轉(zhuǎn)換hsv_src
=
cv.cvtColor(img_src,
cv.COLOR_BGR2HSV)#
3)查表可得綠色高低閾值green_low_hsv
=
(35,
43,
46)green_high_hsv
=
(77,
255,
255)#
4)分割顏色獲得掩模mask_green
=
cv.inRange(hsv_src,
green_low_hsv,
green_high_hsv)#
5)掩模和原圖進(jìn)行位與green
=
cv.bitwise_and(hsv_src,hsv_src,mask
=
mask_green)green
=
cv.cvtColor(green,cv.COLOR_HSV2BGR)#
6)顯示圖像cv.imshow('src',
img_src)cv.imshow('mask_green',
green)
程序運(yùn)行效果如圖
0-1
所示,將利用
inRange()函數(shù),輸入綠色顏色空間閾值,將綠
色從原圖中分割開來。圖
0-1
綠色分割效果(3)數(shù)字圖像二值化在數(shù)字圖像處理中,圖像二值化(Image
Binarization)是指將圖像上的灰度值按
照某種方式設(shè)置為
0
或
255,得到一張黑白分明二值圖像的過程。在二值化圖像中,只存
在二種顏色黑色(0)和白色(maxval
最大值)。圖像二值化可以使邊緣變得更加明顯,
邊緣是指像素值急劇變化的地方,而
0
到
255
的跳變將使得邊緣信息更加突出,如圖
0-2cv.waitKey(0)cv.destroyAllWindows()所示。二值化圖像經(jīng)常出現(xiàn)在圖像處理中,如掩模、圖像分割、輪廓查找等應(yīng)用中。圖
0-2
數(shù)字圖像二值化二值化分為全局閾值二值化和自適應(yīng)(局部)二值化。全局閾值二值化指根據(jù)自定
義閥值對圖像進(jìn)行二值化處理,即灰度值大于閥值時設(shè)該像素灰度值為
255,灰度值小于
閾值時設(shè)該像素灰度值為
0。在
OpenCV
中,使用
cv2.threshold()函數(shù)實(shí)現(xiàn)簡單全局閾值
二值化,函數(shù)參數(shù)說明如表
5-1
所示:表
5-1
threshold
函數(shù)函數(shù)名稱cv2.threshold函數(shù)原型threshold(src,
thresh,
maxval,
type[,
dst])
->
retval,
dst必填參數(shù)src:傳入待二值化的灰度圖thresh:比較閾值(0-255)maxval:最大值(0-255)type:閾值處理方式cv2.THRESH_BINARY
超過閾值部分取
maxval(最大值),否則取
0
cv2.THRESH_BINARY_INV
THRESH_BINARY
的反轉(zhuǎn)
cv2.THRESH_TRUNC
大于閾值部分設(shè)為閾值,否則不變
cv2.THRESH_TOZERO
大于閾值部分不改變,否則設(shè)為
0
cv2.THRESH_TOZERO_INV
THRESH_TOZERO
的反轉(zhuǎn)默認(rèn)參數(shù)無返回值返回兩個值
retval,
dst。retval
表示該次二值化使用的
thresh
值,dst
二值圖像調(diào)用示例ret,
thresh_binary
=
cv2.threshold(gray,
127,
255,
cv2.THRESH_BINARY)簡單閾值二值化是指設(shè)置一個全局閾值,用該閾值對灰度圖像素值進(jìn)行歸類。具體
做法是,像素點(diǎn)灰度值小于等于閾值時將該點(diǎn)置
0(反轉(zhuǎn)置
maxval),大于閾值置
maxval(反轉(zhuǎn)置
0)。自適應(yīng)閾值二值化同全局二值化有較大區(qū)別,全局二值化只使用一個全局閾值來對
圖像進(jìn)行二值化處理,而自適應(yīng)閾值使用每個塊中的平均值或加權(quán)平均值作為閾值。從數(shù)學(xué)角度上看自適應(yīng)閾值較簡單閾值有更好的局部處理能力,從實(shí)際應(yīng)用角度上看兩種
二值化算法各有優(yōu)劣。簡單閾值勝在處理速度和某些特定場景的二值化表現(xiàn)更優(yōu),而自
適應(yīng)閾值則在對局部過曝場景中二值化表現(xiàn)更優(yōu)。因此在實(shí)際應(yīng)用場景中需要根據(jù)場景
特點(diǎn)選擇合適的二值化處理函數(shù),通常先使用全局閾值調(diào)參,效果不好再考慮使用自適
應(yīng)閾值二值化。OpenCV
提供了函數(shù)
cv2.adaptiveThreshold()來實(shí)現(xiàn)自適應(yīng)閾值二值化,函數(shù)參數(shù)說
明如表
5-2
所示:表
5-2
自適應(yīng)閾值二值化函數(shù)名稱cv2.adaptiveThreshold函數(shù)原型adaptiveThreshold(src,
maxValue,
adaptiveMethod,
thresholdType,
blockSize,
C[,
dst])
->
dst必填參數(shù)src:傳入待二值化的灰度圖maxValue:最大值(0-255)adaptiveMethod:cv2.ADAPTIVE_THRESH_MEAN_C
值取自相鄰區(qū)域的平均值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C
值取值相鄰區(qū)域的加權(quán)和
,權(quán)重為高斯
窗口thresholdType:閾值處理方式cv2.THRESH_BINARY
#超過閾值部分取
maxval(最大值),否則取
0
cv2.THRESH_BINARY_INV
THRESH_BINARY
的反轉(zhuǎn)
cv2.THRESH_TRUNC
#大于閾值部分設(shè)為閾值,否則不變
cv2.THRESH_TOZERO
#大于閾值部分不改變,否則設(shè)為
0
cv2.THRESH_TOZERO_INV
#THRESH_TOZERO
的反轉(zhuǎn)blockSize:鄰域大小
用來計(jì)算自適應(yīng)閾值的區(qū)域大小C:常數(shù)
C,閾值等于平均值或者加權(quán)平均值減去這個常數(shù)默認(rèn)參數(shù)無返回值返回值
dst
二值圖像調(diào)用示例dst
=
cv2.adaptiveThreshold(img,
255,cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
11,
2)對比全局閾值二值化和自適應(yīng)閾值二值化效果如圖
0-3
所示,圖中左一為原灰度圖,右二為原灰度圖使用簡單閾值二值化圖,左三為原灰度圖使用自適應(yīng)二值化圖,鄰域均值,右四為原灰度圖使用自適應(yīng)二值化圖,高斯加權(quán)均值。圖
0-3
二值化結(jié)果對比圖像幾何變換幾何變換不改變圖像的像素值,只是在圖像平面上進(jìn)行像素的重新安排。一個幾何
變換需要兩部分運(yùn)算:首先是空問變換所需的運(yùn)算,如平移、旋轉(zhuǎn)和鏡像等,需要用它
來表示輸出圖像與輸入圖像之間的像素映射關(guān)系;此外,還需要使用灰度插值算法,因?yàn)榘凑者@種變換關(guān)系進(jìn)行計(jì)算,輸出圖像的像素可能被映射到輸入圖像的非整數(shù)坐標(biāo)上。(1)圖像平移平移是二維上空間的操作,是指將一個點(diǎn)或一整塊像素區(qū)域沿著
X、Y
方向移動指定
),可以使用如下矩
陣構(gòu)建表示:使用如下代碼來構(gòu)建平移描述矩陣:#
X
軸移動
100
個像素單位,Y
軸移動
50
個像素單位
M=np.float32([[1,0,100],
[0,1,50]])圖
0-4
圖像平移]在
OpenCV
中進(jìn)行圖像平移操作,如圖
4-7,首先使用
Numpy
構(gòu)建出一個平移描述矩
陣,然后將該矩陣作為參數(shù)傳遞到函數(shù)
cv2.warpAffine
中進(jìn)行幾何變換,幾何變換函數(shù)
用法如表
5-3
所示:表
5-3
幾何變換函數(shù)函數(shù)名稱cv2.
warpAffine函數(shù)原型warpAffine(src,
M,
dsize[,
dst[,
flags[,
borderMode[,
borderValue]]]])
->
dst必填參數(shù)src:傳入待幾何變換的灰度圖或彩色圖M:幾何變換描述矩陣
如旋轉(zhuǎn):M
=
cv2.getRotationMatrix2D((w
/
2,
h
/
2),
45,
.6)dsize:指定幾何變換后輸出圖像的(寬,高)默認(rèn)參數(shù)flags:插值方式cv2.INTER_NEAREST
最鄰近插值,將離新像素所在位置最近的像素像素值賦值給新像素cv2.INTER_LINEAR
雙線性插值,
x、y
方向臨近像素取乘以相應(yīng)權(quán)重并相加賦值給
i
新的像素值cv2.INTER_CUBIC
雙立方插值,
精度更高,計(jì)算量最大,取附近十六個點(diǎn)加權(quán)取像素值cv2.INTER_LANCZOS4
附近像素及原像素加權(quán)取值borderModer:填充模式BORDER_CONSTANT
=
0
以
borderValue
值填充邊界
BORDER_REPLICATE
=
1
拉伸填充BORDER_WRAP
=
3
溢出填充BORDER_DEFAULT
=
4
鏡像填充
BORDER_REFLECT
=
2
鏡像填充bordValue:邊界填充值
0-255返回值幾何變換后的圖像調(diào)用示例dst
=
cv2.warpAffine(img,
M,
(cols,
rows))圖像平移示例代碼:import
cv2import
numpy
as
np#
讀取圖片,路徑自定義img
=
cv2.imread("Resources/SunsetSea.png",
17)#
獲取圖片高寬imageInfo
=
img.shapeh
=
imageInfo[0]w
=
imageInfo[1]#
圖像平移array
=
np.array([[1,
0,
100],
[0,
1,
100]],
np.float32)dst
=
cv2.warpAffine(img,
array,
(w,
h))#
顯示原圖及平移后的圖像cv2.imshow("src
Image",
img)
程序運(yùn)行結(jié)果如圖
0-5
所示圖
0-5
平移填充實(shí)驗(yàn)結(jié)果(2)圖像縮放圖像縮放是指將一副圖像放大或縮小得到新圖像。對一張圖像進(jìn)行縮放操作,可以
按照比例縮放,也可指定圖像寬高進(jìn)行縮放。放大圖像即是對圖像矩陣進(jìn)行拓展,而縮
小即是對圖像矩陣進(jìn)行壓縮。放大圖像會增大圖像文件大小,同樣縮小圖像會減小文件
體積,如圖
0-6
所示:cv2.imshow("dst
Image",
dst)cv2.waitKey(0)圖
0-6
圖像縮放OpenCV
中提供了函數(shù)
cv2.resize
實(shí)現(xiàn)圖像縮放,詳細(xì)參數(shù)如表
5-6:表
5-6
圖像縮放函數(shù)函數(shù)名稱cv2.resize函數(shù)原型resize(src,
dsize[,
dst[,
fx[,
fy[,
interpolation]]]])
->
dst必填參數(shù)src:傳入待幾何變換的灰度圖或彩色圖dsize:指定幾何變換后輸出圖像的(寬,高)默認(rèn)參數(shù)fxx:軸縮放比例fyy:軸縮放比例Interpolation:插值方式cv2.INTER_NEAREST
最鄰近插值,將離新像素所在位置最近的像素像素值賦值給新像素cv2.INTER_LINEAR
雙線性插值,
x、y
方向臨近像素取乘以相應(yīng)權(quán)重并相加賦值給
i
新的像素值cv2.INTER_CUBIC
雙立方插值,
精度更高,計(jì)算量最大,取附近十六個點(diǎn)加
權(quán)取像素值cv2.INTER_LANCZOS4
附近像素及原像素加權(quán)取值返回值幾何變換后的圖像(3)圖像旋轉(zhuǎn)圖像旋轉(zhuǎn)是二維上空間的操作,是指將一塊區(qū)域的像素,以指定的中心點(diǎn)坐標(biāo),按
照逆時針方向旋轉(zhuǎn)到指定角度得到旋轉(zhuǎn)后的圖像。對圖像進(jìn)行旋轉(zhuǎn)操作時需要預(yù)先構(gòu)建
一個旋轉(zhuǎn)描述矩陣,指定旋轉(zhuǎn)中心點(diǎn)和旋轉(zhuǎn)的角度。圖
0-7
所示是旋轉(zhuǎn)
90
度的效果示意
圖:圖
0-7
圖像旋轉(zhuǎn)示意圖在
OpenCV
中進(jìn)行圖像旋轉(zhuǎn),需先構(gòu)造出旋轉(zhuǎn)描述矩陣,構(gòu)建旋轉(zhuǎn)描述矩陣函數(shù)參數(shù)說明如表
5-7
所示:表
5-7
構(gòu)造旋轉(zhuǎn)描述矩陣函數(shù)名稱cv2.getRotationMatrix2D函數(shù)原型getRotationMatrix2D(center,
angle,
scale)
->
retval必填參數(shù)center:指定旋轉(zhuǎn)中心點(diǎn)angle:angle:旋轉(zhuǎn)角度(負(fù)數(shù)順時針旋轉(zhuǎn),正數(shù)逆時針旋轉(zhuǎn))scale:縮放因子,小于
1
縮小,
等于
1
不縮放,
大于
1
放大默認(rèn)參數(shù)無返回值返回旋轉(zhuǎn)描述矩陣調(diào)用示例M
=
cv2.getRotationMatrix2D((w
/
2,
h
/
2),
45,
.6)構(gòu)造好的旋轉(zhuǎn)描述矩陣后,將它傳遞到函數(shù)
cv.warpAffine
中進(jìn)行幾何變換。圖像旋轉(zhuǎn)示例程序如下:
圖像旋轉(zhuǎn)實(shí)驗(yàn)結(jié)果如圖
0-8
所示:import
cv2
as
cvimport
numpy
as
np#
讀取圖片img
=
cv2.imread("Resources/SunsetSea.png",
17)#
獲取圖片高寬imageInfo
=
img.shapeh
=
imageInfo[0]w
=
imageInfo[1]#
圖像旋轉(zhuǎn)rotate
=
cv2.getRotationMatrix2D((w
/
2,
h
/
2),
30,
.5)dst
=
cv2.warpAffine(img,
rotate,
(w,
h))#
結(jié)果顯示cv2.imshow("src
Image",
img)cv2.imshow("dst
Image",
dst)cv2.waitKey(0)cv.waitKey(0)圖
0-8
圖像旋轉(zhuǎn)(4)仿射變換仿射變換(affine
transform)是二維圖像上的線性變換加平移操作,如圖
0-9
所
示,Image1
先經(jīng)過旋轉(zhuǎn)(線性變換),再進(jìn)行縮放(線性變換),最后進(jìn)行平移(向量
加)就可得到
Image2:圖
0-9
仿射變換圖
0-9
中
Image1
到
Image2
的轉(zhuǎn)變是仿射變換,原圖中所有的平行線在變換后的圖像中同樣平行。進(jìn)行仿射變換需要先確定原圖中三個不共線的點(diǎn),以及目標(biāo)圖像中對應(yīng)三點(diǎn)的映射
位置,使用函數(shù)
getAffineTransform()來構(gòu)建仿射描述矩陣
M,將描述矩陣傳入函數(shù)
warpAffine()得到仿射變換目標(biāo)圖像。仿射變換示例代碼如下所示:原圖變換的頂點(diǎn)
從左上角開始
逆時針方向填入
程序運(yùn)行結(jié)果如圖
0-10
所示:pts1
=
np.float32([[50,
50],
[400,
50],
[50,
400]])#
目標(biāo)圖像變換頂點(diǎn)
從左上角開始
逆時針方向填入pts2
=
np.float32([[100,
100],
[300,
50],
[100,
400]])#
構(gòu)建仿射變換描述矩陣M
=
cv.getAffineTransform(pts1,
pts2)#
進(jìn)行仿射變換dst
=
cv.warpAffine(img,
M,
(cols,
rows))圖
0-10
仿射變換結(jié)果(5)透視變換透視變換(perspective
transform)本質(zhì)是將圖像投影到一個新的視平面,仿射變
換可理解為透視變換的一種特殊形式。仿射變換與透視變換在圖像還原、圖像局部變化
處理方面有重要意義。仿射變換是
2D
平面變換,透視變換時
3D
空間變換。仿射變換需要
先確定原圖中三個頂點(diǎn)坐標(biāo),而透視變換需要先確定原圖中四點(diǎn)坐標(biāo)(任意三點(diǎn)不共
線)。下面給出透視變換示例代碼。
import
cv2
as
cvimport
numpy
as
np#
讀取原圖img
=
cv.imread('./sudoku.jpg')h,
w,
c
=
img.shape
print(h,
w)#
首先確定原圖中四點(diǎn)坐標(biāo)pts1
=
np.float32([(56,
65),
(28,
387),
(389,
390),
(368,
52)])
pts2
=
np.float32([(0,
0),
(0,
h),
(w,
h),
(w,
0)])M
=
cv.getPerspectiveTransform(pts1,
pts2)
dst
=
cv.warpPerspective(img,
M,
(w,
h))#
在原圖中標(biāo)記這些頂點(diǎn)cv.circle(img,
tuple(pts1[0]),
1,
(0,
255,
255),
cv.LINE_AA)
cv.circle(img,
tuple(pts1[1]),
1,
(255,
0,
255),
cv.LINE_AA)
cv.circle(img,
tuple(pts1[2]),
1,
(255,
255,
255),
cv.LINE_AA)
cv.circle(img,
tuple(pts1[3]),
1,
(0,
0,
0),
cv.LINE_AA)#
在目標(biāo)圖中標(biāo)記頂點(diǎn)cv.circle(dst,
tuple(pts2[0]),
1,
(0,
255,
255),
cv.LINE_AA)
cv.circle(dst,
tuple(pts2[1]),
1,
(255,
0,
255),
cv.LINE_AA)
cv.circle(dst,
tuple(pts2[2]),
1,
(255,
255,
255),
cv.LINE_AA)
cv.circle(dst,
tuple(pts2[3]),
1,
(0,
0,
0),
cv.LINE_AA)#
結(jié)果顯示
cv.imshow('img',
img)
cv.imshow('dst',
dst)
程序運(yùn)行結(jié)果如圖
0-11
所示:圖
0-11
透視變換結(jié)果對比(左原圖,右為變換后的圖)透視變換常用于車牌矯正,車牌矯正需要找到車牌區(qū)域四個頂點(diǎn)坐標(biāo),左上記為點(diǎn)
A,
右上記為點(diǎn)
B,左下記為點(diǎn)
C,右下記為點(diǎn)
D。假設(shè)原圖中四點(diǎn)坐標(biāo)為
A(88,
92)、B(218,118)、C(84,125)、D(211,
160)。
四
個
頂
點(diǎn)
坐
標(biāo)
中
x
和
y
最
大
最
小
值
記
為x_min,x_max,y_min,y_max,四個頂點(diǎn)坐標(biāo)映射坐標(biāo)為
A(x_min,y_min)、B(x_max,
y_min)、C(x_min,
y_max)、D(x_max,y_max)。車牌矯正參考代碼如下:cv.waitKey(0)cv.destroyAllWindows()
最終矯正效果如圖
0-12
所示:圖
0-12
透視變換傾斜矯正形態(tài)學(xué)操作(1)腐蝕圖像腐蝕也即是“收縮”或“細(xì)化”二值圖像中的對象。如圖
4-16
所示,假設(shè)用一#
原圖中車牌四頂點(diǎn)坐標(biāo)pts1
=
np.float32([(88,
92),
(218,
118),
(84,
125),
(211,
160)])#
矯正后車牌四頂點(diǎn)坐標(biāo)pts2
=
np.float32([(88,
118),
(218,
118),
(88,
160),
(218,
160)])#
構(gòu)建透視變換描述矩陣M
=
cv.getPerspectiveTransform(pts1,
pts2)#進(jìn)行透視變換——圖像校正dst
=
cv.warpPerspective(img,
M,
(w,
h))個
3X3
的全一矩陣去腐蝕一張灰度圖,中心錨點(diǎn)的值就會被替換為對應(yīng)核中最小的值。圖
4-16
腐蝕原理OpenCV
中使用函數(shù)
cv2.erode
來進(jìn)行腐蝕操作。cv2.erode
函數(shù)參數(shù)說明如下表
4-12
所示:表
4-12
腐蝕函數(shù)函數(shù)名稱cv2.erode函數(shù)原型erode(src,
kernel[,
dst[,
anchor[,
iterations[,
borderType[,
borderValue]]]]])
->
dst必填參數(shù)src:指定要腐蝕的灰度圖或二值化圖像kernel:腐蝕操作的內(nèi)核。
如果該參數(shù)不指定,默認(rèn)為一個簡單的
3x3
全
一
矩
陣
,
否
則
,
就
需
要
明
確
指
定
它
的
形
狀
,
可
以
使
用
函
數(shù)
getStructuringElement()獲取結(jié)構(gòu)化元,也可以指定自定義腐蝕核。默認(rèn)參數(shù)anchor:錨點(diǎn),默認(rèn)為-1
表示內(nèi)核中心點(diǎn),省略時為默認(rèn)值iterations
迭代次數(shù)。省略時為默認(rèn)值
1borderType:推斷邊緣類型,具體參見
borderInterpolate
函數(shù)。默認(rèn)值為
邊緣值拷貝borderValue:邊緣填充值,具體可參見
createMorphoogyFilter
函數(shù),可
省略返回值返回腐蝕操作后的結(jié)果圖像調(diào)用示例kernel
=
np.ones((3,
3),
np.uint8)
erosion
=
cv2.erode(img,
kernel,
iterations
=
1)圖像腐蝕會使白色區(qū)域的邊緣像素值減小,從而使白色區(qū)域的面積減少。迭代次數(shù)
越多腐蝕效果越明顯,內(nèi)核大小越大腐蝕效果越明顯。因此腐蝕可以用來去除圖像中細(xì)
小的白色區(qū)域,可以用來斷開連接在一起的的白色區(qū)域塊,腐蝕會明顯減少白色區(qū)域面
積。多次腐蝕效果如圖
4-17
所示:圖
4-17
連續(xù)腐蝕效果(2)膨脹與腐蝕操作相反,膨脹是在二值圖像中“加長”或“變粗”的操作,如圖
4-18
所示,
使用一個
3X3
的全一矩陣去膨脹一張灰度圖,中心錨點(diǎn)的值就會被替換為對應(yīng)核中最大
的值。圖
4-18
膨脹原理因此膨脹的效果是增大白色區(qū)域的面積,其原理是在原圖的小區(qū)域內(nèi)取局部最大值。OpenCV
中使用函數(shù)
cv2.dilate
來進(jìn)行膨脹操作,其參數(shù)說明如表
4-13
所示:表
4-13
膨脹原理函數(shù)名稱cv2.dilate函數(shù)原型dilate(src,
kernel[,
dst[,
anchor[,
iterations[,
borderType[,
borderValue]]]]])
->
dst必填參數(shù)src:指定要膨脹的灰度圖或二值化圖像,彩色圖像也可以,但一般不這么做kernel:膨脹操作的內(nèi)核。
如果不指定,默認(rèn)為一個簡單的
3x3
全一矩陣,否則,就要明確指定它的形狀,可以使用函數(shù)
getStructuringElement()獲取結(jié)構(gòu)化元,也可以指定自定義膨脹核默認(rèn)參數(shù)anchor:錨點(diǎn),默認(rèn)為-1
表示內(nèi)核中心點(diǎn),省略時為默認(rèn)值iterations:迭代次數(shù)。省略時為默認(rèn)值
1borderType:推斷邊緣類型,具體參見
borderInterpolate
函數(shù)。默認(rèn)值為邊緣值拷貝borderValue:邊緣填充值,具體可參見
createMorphoogyFilter
函數(shù),可省略返回值返回膨脹操作后的結(jié)果圖像調(diào)用示例kernel
=
np.ones((3,
3),
np.uint8)dilate
=
cv2.dilate(img,
kernel,
iterations=1)膨脹會使白色區(qū)域的邊緣像素值增大,從而使白色區(qū)域的面積減增大。膨脹迭代次
數(shù)越多膨脹效果越明顯,內(nèi)核大小越大膨脹效果越明顯。因此,膨脹可以用來去除圖像
中細(xì)白色區(qū)域內(nèi)細(xì)小的空洞,可以用來連接斷在了的白色區(qū)域,膨脹明顯增加白色區(qū)域
面積。多次膨脹效果如圖
4-19
所示。圖
4-19
多次膨脹效果圖像濾波圖像濾波,即在盡量保留圖像細(xì)節(jié)特征的條件下對目標(biāo)圖像的噪聲進(jìn)行抑制,是圖
像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有
效性和可靠性。(1)均值濾波均值濾波是平滑線性濾波器中的一種,具有平滑圖像過濾噪聲的作用。均值濾波的
思想即使用濾波器模板
w
所包含像素的平均值去覆蓋中心錨點(diǎn)的值。在
OpenCV
中可以使用函數(shù)
cv2.blur
或
cv2.boxFilter
做均值濾波,這兩個函數(shù)的詳細(xì)用法如表
4-14
和表
4-15
所示:表
4-14
均值濾波函數(shù)
blur函數(shù)名稱cv2.blur函數(shù)原型blur(src,
ksize[,
dst[,
anchor[,
borderType]]])
->
dst必填參數(shù)src:傳入待濾波的圖像彩色圖或單通道圖ksize:模板大小
如(3,3)表示
3X3
模板默認(rèn)參數(shù)anchor:錨點(diǎn);默認(rèn)值
Point(-1,-1)表示錨位于內(nèi)核中央borderType:borderType:邊框模式用于圖像外部的像素,
默認(rèn)邊緣像素拷貝返回值均值濾波后的圖像調(diào)用示例blur
=
cv.blur(img,
(3,
3))表
4-15
均值濾波函數(shù)
boxFilter函數(shù)名稱cv2.boxFilter函數(shù)原型boxFilter(src,
ddepth,
ksize[,
dst[,
anchor[,
normalize[,
borderType]]]])
->
dst必填參數(shù)src:傳入待濾波的圖像彩色圖或單通道圖ddepth:指定輸出圖像深度,-1
表示與
src
深度保持一致ksize:模板大小
如(3,3)表示
3X3
模板默認(rèn)參數(shù)anchor:錨點(diǎn):默認(rèn)值
Point(-1,-1)表示錨位于內(nèi)核中央normalize:normalize
flag,指定內(nèi)核是否按其區(qū)域進(jìn)行規(guī)范化borderType:borderType:邊框模式用于圖像外部的像素,
默認(rèn)邊緣像素拷貝返回值濾波后的圖像調(diào)用示例blur_b
=
cv2.boxFilter(img,
-1,
(3,
3))均值濾波公式如下:}對原始圖像稍顯模糊使用
5X5
模板進(jìn)行均值濾波,對于尺寸稍小的亮點(diǎn),使用均值
濾波后亮度明顯降低;對于尺寸非常小的亮點(diǎn),使用均值濾波后亮點(diǎn)消失融入背景,如
圖
4-20
所示:圖
4-20
5X5
均值濾波結(jié)果對原始圖像十分模糊使用
9X9
模板進(jìn)行均值濾波,對于尺寸較大的亮點(diǎn),濾波后亮
度明顯降低;對于尺寸稍小的亮點(diǎn),濾波后亮點(diǎn)消失融入背景,如圖
4-21
所示:圖
4-21
9X9
均值濾波最后使用不同大小的模板,對同一張圖進(jìn)行均值濾波實(shí)驗(yàn),實(shí)驗(yàn)效果如圖
4-22
所示:圖
4-22
不同尺寸均值濾波結(jié)果對比根據(jù)上述實(shí)驗(yàn)可知,均值濾波能夠消除小尺寸圖像亮點(diǎn)。同時濾波器模板尺寸越大,
濾波后的圖像越模糊/平滑,但也越模糊,因此,在實(shí)際應(yīng)用中,應(yīng)選擇合適大小的濾波
器模板進(jìn)行圖像濾波。(2)中值濾波中值濾波是一種基于統(tǒng)計(jì)排序的非線性濾波器,能有效抑制噪聲,如非線性噪聲,
平滑其它非脈沖噪聲,減少物體邊界細(xì)化或粗化的失真。與線性濾波器均值濾波相比,
均值無法消除椒鹽噪聲,中值濾波卻可以輕松去除。中值濾波容易斷開圖像中的縫隙,
如字符縫隙,均值濾波可以連通圖像中的縫隙。中值濾波計(jì)算原理如圖
4-23
所示:圖
4-23
中值濾波原理中值濾波計(jì)算方法為:濾波輸出像素點(diǎn)
g(x,
y)
=
濾波模板
domain
定義的排列集合
的中值。使用中值濾波時需要注意以下幾點(diǎn):濾波模板
domain
的中心與像素點(diǎn)
f(s,
y)重合;濾波器模板
domain
為
0/1
矩陣,與
domain
中元素
1
對應(yīng)的像素才參與排序;對參與排序的像素點(diǎn)進(jìn)行升序排序,g(x,y)=排序集合的中值。在
OpenCV
中使用
cv2.medianBlur
來進(jìn)行中值濾波去除椒鹽噪聲,函數(shù)參數(shù)說明如表
4-16
所示:表
4-16
中值濾波函數(shù)函數(shù)名稱cv2.medianBlur函數(shù)原型medianBlur(src,
ksize[,
dst])
->
dst必填參數(shù)src:傳入待濾波的圖像彩色圖或單通道圖ksize:模板大小
傳一個正奇數(shù),而不是一個元組默認(rèn)參數(shù)無返回值中值濾波后的圖像調(diào)用示例blur_b
=
cv2.
medianBlur(img,
3)中值濾波能有效去除椒鹽噪聲,椒鹽噪聲也稱脈沖噪聲,是一種隨機(jī)出現(xiàn)的白點(diǎn)或
者黑點(diǎn)。椒鹽噪聲的成因可能是影像訊號受到突如其來的強(qiáng)烈干擾而產(chǎn)生。中值濾波去除椒鹽噪聲實(shí)驗(yàn)結(jié)果如圖
4-24
所示:圖
4-24
不同尺寸中值濾波結(jié)果對比根據(jù)實(shí)驗(yàn)結(jié)果可知,中值濾波能高效濾除椒鹽噪聲,如椒鹽白噪聲、椒鹽黑噪聲和
其他脈沖噪聲,如類似老式電視雪花噪點(diǎn),但同時也容易丟失圖像邊緣信息,造成圖像
縫隙,如
OCR
中斷開單字符連通,當(dāng)使用較大核濾波時容易誤將真實(shí)邊界當(dāng)作噪聲去除。使用中值濾波函數(shù)
cv.medianBlur()時,值得注意的是核大小需是一個正奇數(shù),不能
是一個元組。圖
4-25
是中值濾波案例運(yùn)行的效果圖,可以看到圖片經(jīng)過中值濾波降噪后變得更清
晰。圖
4-25
中值濾波降噪(3)高斯濾波高斯濾波和均值濾波很相似,均值濾波是計(jì)算鄰域內(nèi)所有像素灰度的平均值或加權(quán)
平均值,然后去替換中心點(diǎn)的像素值。高斯濾波是計(jì)算鄰域內(nèi)所有像素灰度的高斯加權(quán)
平均值,然后去替換中心點(diǎn)的像素。二者的主要區(qū)別在于鄰域權(quán)重值的分布,高斯濾波
權(quán)重值符合正態(tài)分布,均值濾波權(quán)重不符合正態(tài)分布。高斯濾波計(jì)算方法如圖
4-26
所示:圖
4-26
高斯濾波原理高斯濾波計(jì)算規(guī)則如下:a.
高斯運(yùn)算結(jié)果
=
高斯權(quán)重矩陣
*
對應(yīng)像素矩陣;
b.
對應(yīng)像素矩陣錨點(diǎn)
=
高斯運(yùn)算結(jié)果矩陣求和;
c.
邊界點(diǎn)默認(rèn)的處理方式是邊緣拷貝。在
OpenCV
中使用函數(shù)
cv2.GaussianBlur
進(jìn)行高斯濾波,函數(shù)參數(shù)說明如表
4-17
所示:表
4-17
高斯濾波函數(shù)函數(shù)名稱cv2.
GaussianBlur函數(shù)原型GaussianBlur(src,
ksize,
sigmaX[,
dst[,
sigmaY[,
borderType]]])
->
dst必填參數(shù)src:傳入待濾波的圖像彩色圖或單通道圖ksize:高斯內(nèi)核大小sigmaX:高斯核函數(shù)在
X
方向上的正態(tài)分布標(biāo)準(zhǔn)偏差默認(rèn)參數(shù)sigmaY:高斯核函數(shù)在
Y
方向上的標(biāo)準(zhǔn)偏差,如果
sigmaY
是
0,會自動將
sigmaY
的值設(shè)置為與
sigmaX
相同的值borderType:borderType:邊框模式用于圖像外部的像素,
默認(rèn)邊緣像素拷貝返回值濾波后的圖像調(diào)用示例g_blur
=
cv2.GaussianBlur(img,
(kw,
kh),
0.1,
0.2)使用不同的高斯核大小,進(jìn)行高斯濾波結(jié)果如圖
4-27
所示:圖
4-27
去除高斯型噪聲對比結(jié)果根據(jù)圖
4-27
可知,高斯濾波只能去除高斯噪聲,無法去除椒鹽噪聲、脈沖噪聲;高斯濾波在使用較大高斯內(nèi)核時,降噪能力明顯加強(qiáng),但模糊效果
卻沒有明顯增強(qiáng),這使得在使用大核時也可以較好的保存邊界信息。高斯小核過濾小尺寸高斯噪聲,大核過濾較大尺寸噪聲。隨著核大小增大,降噪能力增強(qiáng)。但邊緣信息依然能得到較好的保留。圖像邊緣檢測與輪廓提取圖像輪廓是指具有相同顏色或灰度值的連續(xù)點(diǎn)連接在一起的曲線,對圖像的輪廓進(jìn)
行檢測在形狀分析和物體識別應(yīng)用場景中十分重要。圖像輪廓檢測方法通常需定義亮度、
顏色等特征的低層突變,通過標(biāo)識圖像中亮度變化明顯的點(diǎn)來完成邊緣檢測。邊緣檢測
通常將圖像與微分算子卷積,比如借助于
Sobel
算子和
Canny
算子等,但此方法沒有考慮
視覺中層和高層信息,因此在含有大量噪聲或者紋理的情況下,難得出完整的目標(biāo)輪廓。檢測圖像中物體輪廓的過程主要有以下四個步驟:步驟
1:首先對輸入圖像做預(yù)處理,通用的方法是采用較小的二維高斯模板做平滑濾
波處理,去除圖像噪聲,采用小尺度的模板是為了保證后續(xù)輪廓定位的準(zhǔn)確性。因?yàn)榇?/p>
尺度平滑往往會入致平滑過渡,從而模糊邊緣,影響邊緣檢測效果。步驟
2:對平滑后的圖像做邊緣檢測處理,利用亮度、顏色等可以區(qū)分物體與背景的
可用梯度特征信息,得到初步的邊緣圖像。步驟
3:對邊緣響應(yīng)做進(jìn)一步處理,得到更好的邊緣響應(yīng)圖像。這個過程通常會涉及
到判據(jù),即對輪廓點(diǎn)和非輪廓點(diǎn)做出不同處理達(dá)到區(qū)分輪廓點(diǎn)和非輪廓點(diǎn)的效果,從而
得到可以作為輪廓的邊緣圖像。步驟
4:根據(jù)上一步驟檢測到的輪廓進(jìn)行精確的定位,最后確定圖像輪廓。因?yàn)樵趯?shí)
際應(yīng)用過程中,上一步驟得到的輪廓檢測結(jié)果往往是不盡人意的,因此需要對其再進(jìn)行
精確地篩選定位。OpenCV
提供了圖像輪廓檢測函數(shù)
cv2.findContours(),以及圖像輪廓繪制函數(shù)
cv2.
drawContours(),函數(shù)參數(shù)說明分別如下表
4-18
所示:表
4-18
圖像輪廓查找函數(shù)函數(shù)名稱cv2.findContours函數(shù)原型findContours(image,
mode,
method[,
contours[,
hierarchy[,
offset]]])
->
contours,
hierarchy必填參數(shù)image:傳入二值化圖像或邊緣檢測算子計(jì)算結(jié)果圖像mode:輪廓檢查模式,有四個可選的值
cv2.RETR_EXTERNAL
表示只提取最外面的輪廓;
cv2.RETR_LIST
表示提取所有輪廓并將其放入列表;cv2.RETR_CCOMP
表示提取所有輪廓并將組織成一個兩層結(jié)構(gòu),其中頂層輪廓是外部輪廓,第二層輪廓是“洞”的輪廓;
cv2.RETR_TREE:表示提取所有輪廓并組織成輪廓嵌套的完整層級結(jié)構(gòu)。method:輪廓的近似方法,有四個可選擇值cv2.CHAIN_APPROX_NONE
獲取每個輪廓的每個像素,相鄰的兩個點(diǎn)的像素位置差不超過
1;cv2.CHAIN_APPROX_SIMPLE
壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點(diǎn)坐標(biāo),如果一個矩形輪廓只
需
4
個點(diǎn)來保存輪廓信息;cv2.CHAIN_APPROX_TC89_L1
和
cv2.CHAIN_APPROX_TC89_KCOS
使用
Teh-Chinl
鏈逼近算法中的一種。返回值舊版
API
返回三個值,新版兩個值。contours
存儲著查找的的輪廓,hierarchy
存儲著查找的輪廓層次關(guān)系。調(diào)用示例contours,
hierarchy
=
cv2.findContours(thresh,
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)[-2:]圖像輪廓繪制函數(shù)如表
4-19:表
4-19
輪廓繪制函數(shù)函數(shù)名稱cv2.drawContours函數(shù)原型drawContours(image,
contours,
contourIdx,
color[,
thickness[,
lineType[,
hierarchy[,
maxLevel[,
offset]]]]])
->
image必填參數(shù)image:繪制輪廓的目標(biāo)圖像,該函數(shù)會修改
image
值,經(jīng)過該函數(shù)處理后,返回值
return_image
與
原
image
相同。
如果需要保存原圖信息,請使用
copycontours:所有的輪廓,是一個
Python
列表contourIdx:輪廓的索引,為-1
時表示繪制
contours
里的所有color:繪制輪廓時使用的顏色默認(rèn)參數(shù)thickness:繪制輪廓的線條寬度,為-1
時表示填充輪廓內(nèi)部lineType:線條的類型hierarchy:層次結(jié)構(gòu)信息,與函數(shù)
findcontours()的
hierarchy
有關(guān)maxLevel:
繪
制
輪
廓
的
最
高
級
別
。
若
為
0,
則
繪
制
指
定
輪
廓
;
若
為
1,
則
繪
制
該
輪
廓
和
所
有
嵌
套
輪
廓
(nested
contours);若為
2,則繪制該輪廓、嵌套輪廓(nested
contours)/子輪廓和嵌套-嵌套輪廓(all
the
nested-to-
nested
contours)/孫輪廓,等等。該參數(shù)只有在層級結(jié)構(gòu)時才用到。offset
:按照偏移量移動所有的輪廓(點(diǎn)坐標(biāo))返回值繪制了輪廓的目標(biāo)圖像調(diào)用示例drawing1
=
cv2.drawContours(src.copy(),
contours,
-1,
(0,
255,
0),
thickness=2,
lineType=cv.LINE_AA)利用如下代碼將檢測出來的所有輪廓繪制到原圖中,效果如圖
4-28
所示:drawing1
=
cv.drawContours(src.copy(),
contours,
-1,
(0,
255,
0),
thickness=2,
lineType=8)圖
4-28
圖像輪廓繪制將輪廓繪制到掩模中,示例代碼如下:
程序運(yùn)行效果如圖
4-29
所示:圖
4-29
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- α1-抗胰蛋白酶在慢性阻塞性肺疾病急性加重和社區(qū)獲得性肺炎中的相關(guān)性研究
- 基于皮爾斯符號三元關(guān)系的民俗節(jié)慶品牌設(shè)計(jì)研究-以甘南“香浪節(jié)”品牌設(shè)計(jì)為例
- 基于機(jī)器視覺的輪胎缺陷和花紋深度檢測方法
- 養(yǎng)老院衛(wèi)生間給排水系統(tǒng)技術(shù)措施
- 2025年中學(xué)教師資格考試《綜合素質(zhì)》教育研究方法定性分析與定量分析試題
- 2025年一級建造師考試建筑施工施工圖設(shè)計(jì)原則應(yīng)用試題科目試卷
- 金融行業(yè)資金管控措施分析
- 怪獸們的冒險(xiǎn)750字15篇
- 2025年壓力容器作業(yè)特種作業(yè)操作證考試試卷(壓力容器使用與維護(hù)保養(yǎng))
- 2025年壓力容器作業(yè)特種操作證考前歷年試題
- 肌肉注射課件(共45張課件)
- 改革開放史智慧樹知到期末考試答案2024年
- 院內(nèi)按病種分值付費(fèi)(DIP)專題培訓(xùn)
- 第六單元作文訓(xùn)練:“批判與觀察”高一語文教材同步作文 素材拓展+范文展示(統(tǒng)編版必修下冊)
- 心肺聽診課件
- 中小學(xué)生環(huán)境教育專題教育大綱
- 商務(wù)禮儀之辦公室禮儀課件
- 公司鑰匙移交單
- 綠色施工策劃書(模板)
- 肺癌生活質(zhì)量量表
- GA 1517-2018 金銀珠寶營業(yè)場所安全防范要求
評論
0/150
提交評論