基于opencv的车牌号码识别 必备基础知识
車牌號碼識別 必備基礎知識
- 1、cv2.split 拆分通道
- 2、cv2.merge 通道合并
- 3、cv2.imshow() 和 plt.show()
- 4、卷積及相關操作
- 5、cv2.GaussianBlur() 高斯模糊
- 6、cv2.medianBlur() 中值模糊
- 7、去噪
- 8、cv2.cvtColor (顏色空間轉換函數)
- 9、灰度處理
- 10、cv2.Sobel()
- 11、cv2.convertScaleAbs()函數
- 12、cv2.imshow() 顯示圖像
- 13、cv2.threshold() 簡單閾值函數
- 14、cv2.getStructuringElement()
- 15、cv2.morphologyEx() 形態學變化函數
- 16、開運算、閉運算
- 17、cv2.dilate()、cv2.erode() 膨脹和腐蝕
- 18、cv2.findContours()查找輪廓,cv2.drawContours() 繪制輪廓
- 19、cv2.boundingRect()cv2.rectangle()
- 20、for in 循環
- 21、range()
- 21、image.shape
- 22、list.append()
- 23、plt.barh() plt.bar()繪制柱狀圖
- 24、sorted() 排序函數
- 25、enumerate() 函數
- 26、os.listdir()
- subplot() 切割
- python 創建數組,創建列表
- (1)創建數組
- (2)創建列表
- python 切片操作
1、cv2.split 拆分通道
#拆分通道 import cv2img = cv2.imread('D:/z/car.png') #opencv讀取圖像文件 b, g ,r =cv2.split(img) #順序是b,g,r,不是r,g,b merged = cv2.merge([b,g,r])cv2.imshow('image',img) cv2.imshow("Blue 1", b) cv2.imshow("Green 1", g) cv2.imshow("Red 1", r) cv2.imshow("merged 1", merged) cv2.waitKey(0)運行結果如下圖:
2、cv2.merge 通道合并
import cv2 import numpy as npimg = cv2.imread('D:/z/car.png') b, g ,r =cv2.split(img)zeros = np.zeros(img.shape[:2], dtype = "uint8") merged_r = cv2.merge([zeros,zeros,r]) #通道分量為零可以理解為零矩陣cv2.imshow('image',img) cv2.imshow("Red 1", r) cv2.imshow("merged_r",merged_r) cv2.waitKey(0)運行結果如下:
注:
zeros = np.zeros(img.shape[:2], dtype = "uint8")①
在用numpy 去創建一個矩陣并想用它生成圖片時一定要記住,矩陣中每個元素的類型必須是 dtype=np.uint8 也可以這樣寫 dtype = “uint8”
②
[0:2]是切片的意思,.shape 應當是OpenCV模塊中處理圖片的,是圖片的一個屬性,這個屬性是個列表 ,然后對這個列表切片操作。
img.shape[ : 2] 表示取彩色圖片的長、寬。
img.shape[ : 3] 則表示取彩色圖片的長、寬、通道。
關于img.shape[0]、[1]、[2]
img.shape[0]:圖像的垂直尺寸(高度)
img.shape[1]:圖像的水平尺寸(寬度)
img.shape[2]:圖像的通道數
在矩陣中,[0]就表示行數,[1]則表示列數。
3、cv2.imshow() 和 plt.show()
在用plt.imshow和cv2.imshow顯示同一幅圖時可能會出現顏色差別很大的現象。
這是因為:opencv的接口使用BGR,而matplotlib.pyplot 則是RGB模式
例一:
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('D:/z/love.jpg') #opencv接口 BGR !!!!!! b,g,r = cv2.split(img) img2 = cv2.merge([r,g,b]) #plt接口 RGB !!!!! plt.subplot(121);plt.imshow(img) plt.subplot(122);plt.imshow(img2) plt.show()運行結果如下圖所示:
例二:
import cv2 import matplotlib.pyplot as pltimg = cv2.imread('D:/z/car.png') b,g,r = cv2.split(img) image= cv2.merge([r,g,b]) image_merged = cv2.merge([r,g,b])plt.figure(figsize=(10,6)) plt.subplot(2,3,1), plt.title('image') #原圖 plt.imshow(image), plt.axis('on') plt.subplot(2,3,2), plt.title('image_gray') #灰度圖片 plt.imshow(img,cmap='gray'), plt.axis('off') plt.subplot(2,3,3), plt.title('image_merged') plt.imshow(image_merged), plt.axis('off') plt.subplot(2,3,4), plt.title('r') plt.imshow(r,cmap='gray'), plt.axis('off') # r通道 plt.subplot(2,3,5), plt.title('g') plt.imshow(g,cmap='gray'), plt.axis('off') # g通道 plt.subplot(2,3,6), plt.title('b') plt.imshow(b,cmap='gray'), plt.axis('off') # b通道 plt.show()運行結果如下:
①
轉換為灰度圖
②
plt.subplot(2,3,1)一個窗口顯示多幅圖像,要用到subplot
使用 plt.subplot 來創建小圖。
eg:plt.subplot (2,3,1) 表示將整個圖像窗口分為2行3列,當前位置為1
③
plt.axis('off')關閉坐標軸
4、卷積及相關操作
①
在數字圖像處理領域,早就被廣泛應用于鄰域處理,只是當年的叫法是“濾波器”。
卷積是一種廣泛使用的數學運算,它在處理圖像時對每個像素都計算該像素值和它相鄰的像素值的一個加權和。其實很好理解,就是內積操作。
②
用模板(掩膜/卷積核/濾波器)來進行卷積是非常通用的圖像處理方法,現在的卷積神經網絡就是最成功的一個應用。
傳統的方法是人工挑選卷積核,對于不同的卷積核,可以獲得不同的結果,如圖像模糊、圖像銳化或邊緣檢測。
③
利用水平邊緣卷積核,可以提取出水平的一些直線出來,當然還有垂直邊緣檢測卷積核,可以提取垂直的一些線條出來,這在字符識別、車牌識別很有用。
卷積和相關操作
除了這篇,還有個專題,有很多介紹。
5、cv2.GaussianBlur() 高斯模糊
①
高斯模糊GaussianBlur()中 參數詳解
原型:
cv2.GaussianBlur( SRC,ksize,sigmaX [,DST [,sigmaY [,borderType ] ] ] ) →DST
參數:
src 輸入圖像;圖像可以具有任何數量的信道,其獨立地處理的,但深度應CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
dst 輸出與圖像大小和類型相同的圖像src。
ksize 高斯核大小。 ksize.width 并且 ksize.height 可以有所不同,但它們都必須是正數和奇數?;蛘?#xff0c;它們可以為零,然后從計算 sigma*。
sigma 如果sigma為非正數(負數或0)的話,就會根據ksize來自動計算sigma,計算公式為sigma = 0.3*((ksize-1)*0.5-1)+0.8
sigmaX – X方向上的高斯核標準偏差。
sigmaY – Y方向上的高斯核標準差;如果 sigmaY 為零,則將其設置為等于 sigmaX;如果兩個西格瑪均為零,則分別根據ksize.width 和 進行計算 ksize.height(getGaussianKernel()有關詳細信息,請參見 link);完全控制的結果,無論這一切的語義未來可能的修改,建議指定所有的ksize,sigmaX和sigmaY。
borderType –像素外推方法。
②
在不知道用什么濾波器好的時候,優先高斯濾波 cv2.GaussianBlur(),然后均值濾波 cv2.blur()
③
高斯濾波是一種線性平滑濾波
高斯濾波是對整幅圖像進行加權平均的過程,每一個像素點的值都由其本身和鄰域內的其他像素值經過加權平均后得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素,用模板確定的鄰域內像素的加權平均灰度值去替代模板中心像素點的值。
基于二維高斯函數,構建權重矩陣,進而構建高斯核,最終對每個像素點進行濾波處理(平滑、去噪)
6、cv2.medianBlur() 中值模糊
概念:
中值濾波法是一種非線性平滑技術,它將每一像素點的灰度值設置為該點某鄰域窗口內的所有像素點灰度值的中值。
函數原型:
cv2.medianBlur(src, ksize[, dst]) -> dst
參數說明:
src:待處理的輸入圖像;
ksize:參數表示濾波窗口尺寸,必須是奇數并且大于 1。比如這里是 5,中值濾波器就會使用 5×5 的范圍來計算,即對像素的中心值及其 5×5 鄰域組成了一個數值集,對其進行處理計算,當前像素被其中值替換掉;
dst:參數表示輸出與 src 相同大小和類型的圖像。
中值模糊一般用在存在一些躁聲點圖像,例如白噪聲,可以去除。
一般用來處理圖像的椒鹽噪聲。
7、去噪
去噪有分為時域去噪和頻域去噪
①
時域去噪通常手法為:
中值濾波: Media_Image 中值濾波的原理是拿特征區域在圖像滑動,每一點(與特征區域的中點重合)的值為特征區域所覆蓋的范圍的中值
均值濾波: mean_image 均值濾波的原理是拿特征區域在圖像滑動,每一點(與特征區域的中點重合)的值為特征區域所覆蓋的范圍的均值
高斯濾波: guss_image 高斯濾波的原理類似,只不過特征區域內的每個點做了加權處理,可以根據需要讓哪個單元的權重大,哪個單元的權重小
②
頻域內的去噪
高通濾波 :讓圖像中高頻部分通過,通常會留下邊緣,起到銳化的作用
低通濾波 :讓圖像的低頻部分通過,通常弱化邊緣,會得到比較平緩的圖像
中通濾波:讓圖像中中頻部分通過
高斯濾波
③
關于濾波和模糊:
它們都屬于卷積,不同濾波方法之間只是卷積核不同(對線性濾波而言)
低通濾波器是模糊,高通濾波器是銳化
低通濾波器就是允許低頻信號通過,在圖像中邊緣和噪點都相當于高頻部分,所以低通濾波器用于去除噪點、平滑和模糊圖像。
低通濾波器則是在像素與周圍像素的亮度差值小于一個特定值時,平滑該像素的亮度。主要用于去噪和模糊化,如高斯模糊是最常用的模糊濾波器,是一個削弱高頻信號強度的低通濾波器。
高通濾波器則反之,用來增強圖像邊緣,進行銳化處理。
高通濾波器(HPF)是檢測圖像的某個區域,然后根據像素與周圍像素的亮度差值來提升該像素的亮度的濾波器。也就是說,如果一個像素比它周圍的像素更突出,就會提升它的亮度。
【注意常見的噪聲有椒鹽噪聲和高斯噪聲,椒鹽噪聲可以理解為斑點,隨機出現在圖像中的黑點或白點;高斯噪聲可以理解為拍攝圖片時由于光照等原因造成的噪聲?!?/p>
④
模糊
均值模糊:一般用來處理圖像的隨機噪聲;
中值模糊:一般用來處理圖像的椒鹽噪聲;
自定義模糊:對圖像進行增強,銳化等操作。
8、cv2.cvtColor (顏色空間轉換函數)
cv2.cvtColor(p1, p2) 是顏色空間轉換函數,p1是需要轉換的圖片,p2是轉換成何種格式。
cv2.COLOR_BGR2RGB 將BGR格式轉換成RGB格式
cv2.COLOR_BGR2GRAY 將BGR格式轉換成灰度圖片 (效果不同3、①,我也暫時不知道為啥…)
運行結果如下:
9、灰度處理
在圖像處理過程中,三個通道的數據比較復雜,那就可以先將圖像進行灰度化處理。
灰度化的過程就是將每個像素點的RGB值統一成同一個值?;叶然蟮膱D像將由三通道變為單通道,單通道的數據處理起來就會簡單許多。
具體見上例后兩張圖。
處理1、
img_GRAY = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2GRAY) img_GRAY1 = plt.imshow(img_GRAY, cmap='gray')兩步一起會得到灰色的圖
處理2、
img = cv2.imread('D:/z/car.png',cv2.IMREAD_GRAYSCALE)
運行代碼發現這樣竟然可以直接變成灰度圖,amazing,不知道能不能直接用。
①
plt 畫出的圖像和原圖有色差
opencv的顏色通道順序為[B,G,R],而matplotlib的顏色通道順序為[R,G,B]。
需要把R和B的位置調換一下。
②
進行灰度處理之后,plt顯示的圖片是綠色的
因為還是直接使用plt顯示圖像,它默認使用三通道顯示圖像。
在plt.imshow()添加參數:plt.imshow(img_gray,cmap="gray")就可以顯示灰色了
③
不過,為什么單獨使用plt.imshow(img_gray,cmap="gray")一點用都沒有呀!!(見 5、中最后一張圖)
生氣,如果有機會問問。
④
灰度圖像
指的是R=G=B,灰度圖像只有256種取值可能。
⑤
灰度化處理
減少在圖像處理過程中的計算量。將彩色圖像灰度化處理以后可從起初的0-256256256縮小到0-255這256種情況,能夠大大降低運算量,這是我們在進行圖像處理希望看到的。
(emm…還是不理解為啥就降低運算量了,那圖片不就顏色少了)
10、cv2.Sobel()
概述: 利用Sobel算子進行圖像梯度計算
使用函數 cv2.Sobel()獲取圖像水平、垂直 及 水平和垂直疊加方向的完整邊緣信息。
格式:
cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])
參數:
src: 輸入圖像
ddepth: 輸出圖像的深度(可以理解為數據類型),-1表示與原圖像相同的深度
圖像深度是指存儲每個像素值所用的位數,例如cv2.CV_8U,指的是8位無符號數,取值范圍為0~255,超出范圍則會被截斷(截斷指的是,當數值大于255保留為255,當數值小于0保留為0,其余不變)。
具體還有:CV_16S(16位無符號數),CV_16U(16位有符號數),CV_32F(32位浮點數),CV_64F(64位浮點數)
dx,dy: 當組合為dx=1,dy=0時求x方向的一階導數;當組合為dx=0,dy=1時求y方向的一階導數(如果同時為1,通常得不到想要的結果)
ksize: (可選參數)Sobel算子的大小,必須是1,3,5或者7,默認為3。
求X方向和Y方向一階導數時,卷積核分別為:
scale:(可選參數)將梯度計算得到的數值放大的比例系數,效果通常使梯度圖更亮,默認為1
delta:(可選參數)在將目標圖像存儲進多維數組前,可以將每個像素值增加delta,默認為0
borderType:(可選參數)決定圖像在進行濾波操作(卷積)時邊沿像素的處理方式,默認為BORDER_DEFAULT
返回值: 梯度圖
測試① 理解一下獲取水平垂直方向邊緣信息(?白色的就略掉了)
例1(水平方向):
結果如下圖所示:
例2(垂直方向):
結果如下:
測試② 深度值不同時:
import cv2#載入原圖 img_original=cv2.imread('D:/z/hb.png',0) #求X方向梯度,并且輸出圖像一個為CV_8U,一個為CV_64F img_gradient_X_8U=cv2.Sobel(img_original,-1,1,0) img_gradient_X_64F=cv2.Sobel(img_original,cv2.CV_64F,1,0)#將圖像深度改為CV_8U img_gradient_X_64Fto8U=cv2.convertScaleAbs(img_gradient_X_64F)#圖像顯示 cv2.imshow('X_gradient_8U',img_gradient_X_8U) cv2.imshow('X_gradient_64F',img_gradient_X_64F) cv2.imshow('X_gradient_64Fto8U',img_gradient_X_64Fto8U) cv2.waitKey() cv2.destroyAllWindows()運行結果如下圖所示:
例1:
例2:
(具體為啥會有這種區別,emm…時間問題暫時不展開了,如果小趙老師會而且愿意給我講的話,我再回來給解答哈)
11、cv2.convertScaleAbs()函數
函數格式:cv2.convertScaleAbs(src[,alpha[,beta]])
概述:
通過線性變換將數據轉換成8位[uint8]
先計算數組絕對值,后轉化為8位無符號數
參數:
src:輸入圖像(多維數組)
alpha:比例因子
beta:保存新圖像(數組)前可以增加的值
使用了函數cv2.convertScaleAbs()將圖像深度為其他梯度圖像重新轉化為CV_8U,這是由于函數cv2.imshow()的默認顯示為8位無符號數,即[0,255]
12、cv2.imshow() 顯示圖像
cv2.imread(圖片,**cv2.IMREAD_GRAYSCALE**)
cv2.IMREAD_COLOR:默認參數,讀入一副彩色圖片,忽略alpha通道
cv2.IMREAD_GRAYSCALE:讀入灰度圖片(竟然可以直接變成灰色的)
cv2.IMREAD_UNCHANGED:顧名思義,讀入完整圖片,包括alpha通道
13、cv2.threshold() 簡單閾值函數
閾值的作用是根據設定的值處理圖像的灰度值,比如灰度大于某個數值像素點保留。通過閾值以及有關算法可以實現從圖像中抓取特定的圖形,比如去除背景等。
函數
Python: cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst
參數:
src:表示的是圖片源
thresh:表示的是閾值(起始值)
maxval:表示的是最大值(待填充色值?)
type:表示的是這里劃分的時候使用的是什么類型的算法,常用值為0(cv2.THRESH_BINARY)
cv2.THRESH_BINARY_INV
另外的取值為:
cv2.THRESH_OTSU
cv2.THRESH_TRIANGLE
cv2.THRESH_MASK
cv2.THRESH_BINARY 大于閾值的部分被置為255,小于部分被置為0
cv2.THRESH_BINARY_INV 大于閾值部分被置為0,小于部分被置為255
cv2.THRESH_TRUNC 大于閾值部分被置為threshold,小于部分保持原樣
cv2.THRESH_TOZERO 小于閾值部分被置為0,大于部分保持不變
cv2.THRESH_TOZERO_INV 大于閾值部分被置為0,小于部分保持不變
cv2.THRESH_OTSU,并且把閾值thresh設為0,算法會找到最優閾值,并作為第一個返回值ret返回。
當使用cv2.THRESH_OTSU或cv2.THRESH_TRIANGLE時,閾值是動態的,會根據計算結果返回相應的數值。
尋找方法是遍歷所有可能的閾值,通過一個公式,計算方差,方差最小的閾值就是選中的閾值。
自適應閾值分割。
cv2.THRESH_OTSU使用最小二乘法處理像素點
cv2.THRESH_TRIANGLE使用三角算法處理像素點。
一般情況下,cv2.THRESH_OTSU適合雙峰圖。cv2.THRESH_TRIANGLE適合單峰圖。單峰圖或者雙峰圖指的是灰度直方圖。
14、cv2.getStructuringElement()
Opencv中函數getStructuringElement()可以生成形態學操作中用到的核,函數原型:
getStructuringElement(shape, ksize,Point anchor=Point(-1,-1));
參數:
shape:核的形狀
ksize:核的大小
Point anchor:核中心位置,默認位于形狀中心處
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
橢圓形:MORPH_ELLIPSE;
第二和第三個參數分別是內核的尺寸以及錨點的位置。一般在調用erode以及dilate函數之前,先定義一個Mat類型的變量來獲得
返回值:
對于錨點的位置,有默認值Point(-1,-1),表示錨點位于中心點。element形狀唯一依賴錨點位置,其他情況下,錨點只是影響了形態學運算結果的偏移。
膨脹或者腐蝕操作就是將圖像(或圖像的一部分區域,我們稱之為A)與核(我們稱之為B)進行卷積。
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 5)) print(kernelX)運行結果如下:
15、cv2.morphologyEx() 形態學變化函數
函數形式:dst = cv.morphologyEx(src, op, kernel)
參數:
src: 輸入圖片
op:
MORPH_OPEN – 開運算(Opening operation)先腐蝕再膨脹。開運算可以用來消除小黑點,在纖細點處分離物體、平滑較大物體邊界的同時并不明顯改變其面積。
MORPH_CLOSE – 閉運算(Closing operation)先膨脹再腐蝕。閉運算可以用來排除小黑洞。
MORPH_GRADIENT - 形態學梯度(Morphological gradient)邊緣。可以突出團塊(blob)的邊緣,保留物體的邊緣輪廓。
MORPH_TOPHAT - 頂帽(Top hat)突出亮區。突出比原輪廓亮的部分。
MORPH_BLACKHAT - 黑帽(Black hat)突出暗區。將突出比原輪廓暗的部分。
MORPH_ERODE - 腐蝕 (erode)
MORPH_DILATE - 膨脹 (dilate)
kernel: 利用cv2.getStructuringElement()函數構造
16、開運算、閉運算
開運算和閉運算就是將腐蝕和膨脹按照一定的次序進行處理。但這兩者并不是可逆的,即先開后閉并不能得到原先的圖像。
閉運算用來連接被誤分為許多小塊的對象,而開運算用于移除由圖像噪音形成的斑點。
開運算可以用來消除小黑點,在纖細點處分離物體、平滑較大物體的邊界的 同時并不明顯改變其面積。
閉運算可以用來排除小黑洞。
因此,某些情況下可以連續運用這兩種運算。如對一副二值圖連續使用閉運算和開運算,將獲得圖像中的主要對象。同樣,如果想消除圖像中的噪聲(即圖像中的“小點”),也可以對圖像先用開運算后用閉運算,不過這樣也會消除一些破碎的對象。
17、cv2.dilate()、cv2.erode() 膨脹和腐蝕
這里有比較詳細介紹:形態學圖像處理:膨脹和腐蝕
膨脹與腐蝕能實現多種多樣的功能,主要如下:
消除噪聲;分割(isolate)出獨立的圖像元素,在圖像中連接(join)相鄰的元素;尋找圖像中的明顯的極大值區域或極小值區域;求出圖像的梯度。
腐蝕和膨脹是對 白色部分(高亮部分) 而言的,不是黑色部分。膨脹就是圖像中的高亮部分進行膨脹,“領域擴張”,效果圖擁有比原圖更大的高亮區域。腐蝕就是原圖中的高亮部分被腐蝕,“領域被蠶食”,效果圖擁有比原圖更小的高亮區域。
膨脹就是求局部最大值的操作,腐蝕就是求局部最小值的操作。
使用erode函數,一般我們只需要填前面的三個參數,后面的四個參數都有默認值。而且往往結合getStructuringElement一起使用。
import cv2 import numpy as npimg = cv2.imread('D:/binary.bmp',0) #OpenCV定義的結構元素 kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))#腐蝕圖像 eroded = cv2.erode(img,kernel) #顯示腐蝕后的圖像 cv2.imshow("Eroded Image",eroded);#膨脹圖像 dilated = cv2.dilate(img,kernel) #顯示膨脹后的圖像 cv2.imshow("Dilated Image",dilated); #原圖像 cv2.imshow("Origin", img)#NumPy定義的結構元素 NpKernel = np.uint8(np.ones((3,3))) Nperoded = cv2.erode(img,NpKernel) #顯示腐蝕后的圖像 cv2.imshow("Eroded by NumPy kernel",Nperoded);cv2.waitKey(0) cv2.destroyAllWindows()運行結果如下:
18、cv2.findContours()查找輪廓,cv2.drawContours() 繪制輪廓
cv2.findContours()函數接受的參數為二值圖,即黑白的(不是灰度圖),所以讀取的圖像要先轉成灰度的,再轉成二值圖
函數形式:(查找輪廓)
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
參數:
image: 輸入圖像
mode: 表示輪廓的檢索模式,有四種:
cv2.RETR_EXTERNAL表示只檢測外輪廓
cv2.RETR_LIST檢測的輪廓不建立等級關系
cv2.RETR_CCOMP建立兩個等級的輪廓,上面的一層為外邊界,里面的一層為內孔的邊界信息。如果內孔內還有一個連通物體,這個物體的邊界也在頂層。
cv2.RETR_TREE建立一個等級樹結構的輪廓。
method: 輪廓的近似辦法
cv2.CHAIN_APPROX_NONE存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE壓縮水平方向,垂直方向,對角線方向的元素,只保留該方向的終點坐標,例如一個矩形輪廓只需4個點來保存輪廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
返回值:
contours: 一個列表,每一項都是一個輪廓, 不會存儲輪廓所有的點,只存儲能描述輪廓的點
hierarchy: 一個ndarray, 元素數量和輪廓數量一樣, 每個輪廓contours [ i ] 對應4個hierarchy元素hierarchy [i] [0] ~ hierarchy[i][3],分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,則該值為負數。
函數形式:(繪制輪廓)
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
參數:
image: 指明在哪幅圖像上繪制輪廓。image為三通道才能顯示輪廓
contours: 輪廓本身,在Python中是一個list
contoursldx: 指定繪制輪廓list中的哪條輪廓,如果是 -1,則繪制其中的所有輪廓。
thickness: 表明輪廓線的寬度,如果是-1(cv2.FILLED),則為填充模式。
lineType: 線型
hierarchy: 輪廓結構信息
19、cv2.boundingRect()cv2.rectangle()
用一個最小的矩形,把找到的形狀包起來。
函數形式:
cv2.boundingRect(img) -->(x, y, w, h)
參數:
img是一個二值圖
返回:
四個值,分別是x,y,w,h;
x,y是矩陣左上點的坐標,w,h是矩陣的寬和高
然后利用cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2) 畫出矩形
參數解釋
第一個參數:img是輸入圖像
第二個參數:(x,y)是矩陣的左上點坐標
第三個參數:(x+w,y+h)是矩陣的右下點坐標
第四個參數:(0,255,0)是畫線對應的rgb顏色
第五個參數:2是所畫的線的寬度
運行結果…
哭了…為啥運行不出來…
我也整不明白為啥,就這吧,氣死我啦!!!
小趙老師理理我吧,孩子敲不下去了T_T
20、for in 循環
循環結構的一種,經常用于遍歷字符串、列表、元組、字典等。
格式:
執行流程:
x 依次表示 y 中的一個元素,遍歷完所有元素循環結束
21、range()
函數形式:
range(start, stop[, step])
Python3 range() 返回的是一個可迭代對象(類型是對象),而不是列表類型, 所以打印的時候不會打印列表
參數說明:
start: 計數從 start 開始。默認是從 0 開始。例如range(5) 等價于range(0,5);
stop: 計數到 stop 結束,但不包括 stop。例如:range(0,5)是[0, 1, 2, 3, 4]沒有5
step:步長,默認為1。例如:range(0,5)等價于 range(0, 5, 1)
21、image.shape
輸出三個參數
(高,寬,通道數)
image.shape[0], 圖片高
image.shape[1], 圖片寬
image.shape[2], 圖片通道數
貌似得到的是數組。
22、list.append()
描述:
用于在列表末尾添加新的對象。
語法:
list.append(obj)
參數:
obj:添加到列表末尾的對象。
返回值:
該方法無返回值,但是會修改原來的列表。
eg:
List = [123, 'zxx', 'love', 'z'] List.append( 2022 ) print("New List:", List)運行結果如下:
23、plt.barh() plt.bar()繪制柱狀圖
plt.bar():正常柱狀圖,常見的統計圖;
plt.barh():橫向的柱狀圖,可以理解為正常柱狀圖旋轉了90°。
參數解釋:
plt.bar()
函數形式:bar(x, height, width=0.8, bottom=None, ***, align='center', data=None, **kwargs)
x:表示x坐標,數據類型為int或float類型,刻度自適應調整;也可傳dataframe的object,x軸上等間距排列;
height:表示柱狀圖的高度,也就是y坐標值,數據類型為int或float類型;
width:表示柱狀圖的寬度,取值在0~1之間,默認為0.8;
bottom:柱狀圖的起始位置,也就是y軸的起始坐標;
align:柱狀圖的中心位置,默認"center"居中,可設置為"lege"邊緣;
color:柱狀圖顏色;“r",“b”,“g”,“#123465”,默認“b"
edgecolor:邊框顏色;同上
linewidth:邊框寬度; 像素,默認無,int
tick_label:下標標簽;
log:柱狀圖y周使用科學計算方法,bool類型;
orientation:柱狀圖是豎直還是水平,豎直:“vertical”,水平條:“horizontal”;
plt.barh()
y:表示y坐標,數據類型為int或float類型,刻度自適應調整;也可傳dataframe的object,y軸上等間距排列;
height:表示柱狀圖的長度,也就是x坐標值,數據類型為int或float類型;
width:表示柱狀圖的高度,取值在0~1之間,默認為0.8;
其他參數與plt.bar()類似。
plt.xlabel() 設置x軸標簽
plt.xticks() 設置刻度
24、sorted() 排序函數
函數形式:
sorted(iterable, cmp=None, key=None, reverse=False)
參數說明:
iterable :可迭代對象。
cmp :比較的函數,這個具有兩個參數,參數的值都是從可迭代對象中取出,此函數必須遵守的規則為,大于則返回1,小于則返回-1,等于則返回0。
key :主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自于可迭代對象中,指定可迭代對象中的一個元素來進行排序。
reverse :排序規則,reverse = True 降序 , reverse = False 升序(默認)。
返回值:
返回重新排序的列表。
eg:
L = [('b',3),('a',4),('c',2),('d',1)] newL = sorted(L, key=lambda x:x[1]) #key=lambda x:x[1] 表示按第二個元素升序排列 print(newL)運行結果如下:
25、enumerate() 函數
描述:
enumerate() 函數用于將一個可遍歷的數據對象(如列表、元組或字符串)組合為一個索引序列,同時列出數據和數據下標,一般用在 for 循環當中。
Python 2.3. 以上版本可用,2.6 添加 start 參數。
函數形式:
enumerate(sequence, [start=0])
參數:
sequence:一個序列、迭代器或其他支持迭代對象。
start:下標起始位置的值。
返回值:
返回 enumerate(枚舉) 對象。
eg:
seasons = ['Spring', 'Summer', 'Fall', 'Winter'] list(enumerate(seasons)) seasons = ['Spring', 'Summer', 'Fall', 'Winter'] list(enumerate(seasons, start=1)) seq = ['one', 'two', 'three'] for i, element in enumerate(seq):print(i, element) #輸出的時候i值自動加一,element后移輸出,結果同如下for循環i = 0 seq = ['one', 'two', 'three'] for element in seq:print(i, seq[i]) i += 1運行結果如下:
26、os.listdir()
描述:
用于返回指定的文件夾包含的文件或文件夾的名字的列表
函數形式:
os.listdir(path)
參數:
path:需要列出的目錄路徑
返回值:
返回指定路徑下的文件和文件夾列表
subplot() 切割
描述:
把figure分成nrows*ncols的子圖表示
函數形式:
subplot(nrows, ncols, plot_number)
或者寫成subplot(nrows ncols plot_number)(中間不用逗號,前提是只能是三位數)
參數:
nrows:子圖的行數
ncols:子圖的列數
plot_number :索引值,表示把圖畫在第plot_number個位置(從左下角到右上角)。即圖形的標號
python 創建數組,創建列表
(1)創建數組
Python中沒有數組只有元組和列表
Python中的NumPy模塊最主要的特點就是引入了數組的概念。數組是一些相公類型的數據集合,這些數據按照一定的順序排列,并且每個數據占用大小相同的存儲空間。要使用數組組織數據,首先就要創建數組。NumPy模塊提供了多種創建數組的方法,如下列舉一下:
(1)使用array()函數創建數組
函數可基于序列型的對象(如列表、元組、集合等,還可以是一個已經創建好的數組)
(2)創建等差數組
用arange()函數創建數組
eg:
(3)創建隨機數組
引用numpy模塊的子模塊random中的函數,主要有rand()函數、randn()函數、randint()函數。
rand()函數創建的數組中每個元素都是[0,1)區間內的隨機數
randn()函數創建的數組中的元素是符合標準正態分布(均值為0,標準差為1)的隨機數
randint()函數創建的數組中元素是制定范圍內的隨機整數
(2)創建列表
創建列表的4種方式:
(1)基本語法創建
零個,一個或一系列數據用逗號隔開,放在方括號[ ]內就是一個列表對象。列表內的數據可以是多個數目,不同類型。
eg:
a = [1,23,’開心’,’nice’]
a = [ ] # 創建一個空的列表對象
(2)list創建
①使用list()可以將任意可迭代的數據轉化成列表。用 list([iterable])函數返回一個列表??蛇x參數iterable是可迭代的對象,例如字符串,元組。list()函數將可迭代對象的元素重新返回為列表。
②將字典類型數據作為參數時,返回的列表元素是字典的鍵。
③將range()函數作為參數,返回一個整數元素的列表。
④如果沒有參數list()函數將返回一個空列表。eg:a = list() #創建一個空的列表對象
(3)range()創建整數列表
range() 可以方便的創建整數列表,這在開發中很有用, 語法格式為:
range( [start,] end [,step] )
Start 參數: 可選, 表示起始數字,默認是0;
End 參數: 必選, 表示結尾數字;
Step 參數: 可選, 表示步長, 默認為1
Python3中 range() 返回的是一個range對象, 而不是列表; 我們需要通過 list() 方法將其轉換成列表對象;
注意: 步長為負數, 從右往回數,此時,start應該大于end
(4)推導式生成列表
使用列表推導式可以非常方便的創建列表, 在開發中經常使用;在for循環和if語句重點練習
(5)利用split分割字符串生成列表
字符串調用split方法返回一個由分開的子串組成的列表。
求列表長度:len(list)
python 切片操作
Python切片操作的一般方式:
一個完整的切片表達式包含兩個“ :”,用于分隔三個參數(start_index、end_index、step),當只有一個“ :”時,默認第三個參數step=1。
切片操作基本表達式:
object [ start_index : end_index : step ]
step:正負數均可,其絕對值大小決定了切取數據時的“步長”,而正負號決定了“切取方向”,正表示“從左往右”取值,負表示“從右往左”取值。當step省略時,默認為1,即從左往右以增量1取值。
start_index:表示起始索引(包含該索引本身);該參數省略時,表示從對象“端點”開始取值,至于是從“起點”還是從“終點”開始,則由step參數的正負決定,step為正從“起點”開始,為負從“終點”開始。
end_index:表示終止索引(不包含該索引本身);該參數省略時,表示一直取到數據”端點“,至于是到”起點“還是到”終點“,同樣由step參數的正負決定,step為正時到“終點”,為負時到“起點”。
具體例子:Python切片操作
總結
以上是生活随笔為你收集整理的基于opencv的车牌号码识别 必备基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中的oop是什么意思_什么是面向
- 下一篇: 移动机器人路径规划:人工势场法