[影象處理] Python+OpenCV實現車牌區域識別及Sobel運算元
由於最近太忙,這篇文章只給出相關程式碼供大家學習,過一段時間會詳細的寫一些列Python影象處理的文章,包括各種演算法原理、影象識別、影象增強、影象分類、深度學習等。本篇文章主要呼叫OpenCV庫(cv2)進行車牌區域識別,具體步驟包括:
1.灰度轉換:將彩色圖片轉換為灰度影象,常見的R=G=B=畫素平均值。
2.高斯平滑和中值濾波:去除噪聲。
3.Sobel運算元:提取影象邊緣輪廓,X方向和Y方向平方和開跟。
4.二值化處理:影象轉換為黑白兩色,通常畫素大於127設定為255,小於設定為0。
5.膨脹和細化:放大影象輪廓,轉換為一個個區域,這些區域內包含車牌。
6.通過演算法選擇合適的車牌位置,通常將較小的區域過濾掉或尋找藍色底的區域。
7.標註車牌位置,如果是花兒、人臉、牛角,可能需要特徵提取和訓練。
本篇文章為基礎性文章,希望對你有所幫助,主要提供些思路,也是自己教學的內容。如果文章中存在錯誤或不足之處,還請海涵。同時,推薦大家閱讀我以前的文章瞭解其他知識。
推薦我C++影象系列基礎知識:
https://blog.csdn.net/column/details/eastmount-mfc.html
PSS:2019年1~2月作者參加了CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index
五年來寫了314篇部落格,12個專欄,是真的熱愛分享,熱愛CSDN這個平臺,也想幫助更多的人,專欄包括Python、資料探勘、網路爬蟲、影象處理、C#、Android等。現在也當了兩年老師,更是覺得有義務教好每一個學生,讓貴州學子好好寫點程式碼,學點技術,"師者,傳到授業解惑也",提前祝大家新年快樂。2019我們攜手共進,為愛而生。
一、讀取影象及灰度轉換
程式碼如下:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
imagePath = '10.jpg'
img = cv2.imread(imagePath)
#opencv預設的imread是以BGR的方式進行儲存的
#而matplotlib的imshow預設則是以RGB格式展示
#所以此處我們必須對圖片的通道進行轉換
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度影象處理
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(u"讀入lenna圖的shape為", GrayImage.shape)
#顯示圖形
titles = ['Source Image','Gray Image']
images = [lenna_img, GrayImage]
for i in xrange(2):
plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
cv2.imshow('Gray.bmp', GrayImage)
cv2.waitKey(0)
輸出結果如下圖所示:
二、高斯平滑和中值濾波去噪
這裡原理推薦我以前C++影象處理的文章,如下:https://blog.csdn.net/column/details/eastmount-mfc.html
完整程式碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
imagePath = '10.jpg'
img = cv2.imread(imagePath)
#opencv預設的imread是以BGR的方式進行儲存的
#而matplotlib的imshow預設則是以RGB格式展示
#所以此處我們必須對圖片的通道進行轉換
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度影象處理
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(u"讀入lenna圖的shape為", GrayImage.shape)
#直方圖均衡化
#equ = cv2.equalizeHist(gray)
#高斯平滑
Gaussian = cv2.GaussianBlur(GrayImage, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
#Gaussian = cv2.GaussianBlur(GrayImage, (9, 9),0)
#中值濾波
Median = cv2.medianBlur(Gaussian, 5)
#顯示圖形
titles = ['Source Image','Gray Image', 'Gaussian Image', 'Median Image']
images = [lenna_img, GrayImage, Gaussian, Median]
for i in xrange(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
輸出結果如下圖所示,分別是原圖、灰度影象、高斯處理和中值濾波處理。
三、Sobel運算元提取輪廓和二值化處理
有時還需要加強影象中景物的邊緣和輪廓,邊緣和輪廓通常位於影象中灰度突出的地方,因而可以直觀的想到用灰度的差分對邊緣和輪廓進行提取,通常可以通過梯度運算元進行提取。影象銳化的目的是提高影象的對比度,從而使影象更清晰,通過提高鄰域內畫素的灰度差來提高影象的對比度。本文采用Sobel運算元提取邊緣輪廓。
閾值又稱為臨界值,它的目的是確定出一個範圍,然後這個範圍內的部分使用同一種方法處理,而閾值之外的部分則使用另一種處理方法或保持原樣。常用的包括產生二值圖:當x<T時y=0,當x>=T時y=255(其中T是閾值)。閾值變換在生物學上的應用比較廣泛,常用語細胞影象分割等。本文采用二值化處理將大於等於170畫素的轉換為255,而下於的轉換為0,使得影象更加清晰。
完整程式碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
imagePath = '10.jpg'
img = cv2.imread(imagePath)
#opencv預設的imread是以BGR的方式進行儲存的
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度影象處理
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(u"讀入lenna圖的shape為", GrayImage.shape)
#直方圖均衡化
#equ = cv2.equalizeHist(gray)
# 高斯平滑
Gaussian = cv2.GaussianBlur(GrayImage, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
# 中值濾波
Median = cv2.medianBlur(Gaussian, 5)
# Sobel運算元 XY方向求梯度
x = cv2.Sobel(Median, cv2.CV_8U, 1, 0, ksize = 3) #X方向
y = cv2.Sobel(Median, cv2.CV_8U, 0, 1, ksize = 3) #Y方向
absX = cv2.convertScaleAbs(x) # 轉回uint8
absY = cv2.convertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5,0)
cv2.imshow('dilation2', Sobel)
cv2.waitKey(0)
# 二值化處理 周圍畫素影響
ret, Binary = cv2.threshold(Sobel, 170, 255, cv2.THRESH_BINARY)
cv2.imshow('dilation2',Binary)
cv2.waitKey(0)
#顯示圖形
titles = ['Source Image','Gray Image', 'Gaussian Image', 'Median Image',
'Sobel Image', 'Binary Image']
images = [lenna_img, GrayImage, Gaussian, Median, Sobel, Binary]
for i in xrange(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
輸出結果如下所示:
四、膨脹和腐蝕處理
接下來進行膨脹和腐蝕處理,其中膨脹讓輪廓突出,腐蝕去掉細節。
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
imagePath = '10.jpg'
img = cv2.imread(imagePath)
#opencv預設的imread是以BGR的方式進行儲存的
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度影象處理
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(u"讀入lenna圖的shape為", GrayImage.shape)
#直方圖均衡化
#equ = cv2.equalizeHist(gray)
#高斯平滑 去噪
Gaussian = cv2.GaussianBlur(GrayImage, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
#Gaussian = cv2.GaussianBlur(GrayImage, (9, 9),0)
#中值濾波
Median = cv2.medianBlur(Gaussian, 5)
#Sobel運算元 XY方向求梯度 cv2.CV_8U
x = cv2.Sobel(Median, cv2.CV_32F, 1, 0, ksize = 3) #X方向
y = cv2.Sobel(Median, cv2.CV_32F, 0, 1, ksize = 3) #Y方向
#absX = cv2.convertScaleAbs(x) # 轉回uint8
#absY = cv2.convertScaleAbs(y)
#Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
gradient = cv2.subtract(x, y)
Sobel = cv2.convertScaleAbs(gradient)
cv2.imshow('dilation2', Sobel)
cv2.waitKey(0)
#二值化處理 周圍畫素影響
blurred = cv2.GaussianBlur(Sobel, (9, 9),0) #再進行高斯去噪
#注意170可以替換的
ret, Binary = cv2.threshold(blurred , 90, 255, cv2.THRESH_BINARY)
cv2.imshow('dilation2', Binary)
cv2.waitKey(0)
#膨脹和腐蝕操作的核函式
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7))
# 膨脹讓輪廓突出
Dilation = cv2.dilate(Binary, element2, iterations = 1)
# 腐蝕去掉細節
Erosion = cv2.erode(Dilation, element1, iterations = 1)
# 再次膨脹
Dilation2 = cv2.dilate(Erosion, element2,iterations = 3)
cv2.imshow('Dilation2 ', Dilation2)
cv2.waitKey(0)
#顯示圖形
titles = ['Source Image','Gray Image', 'Gaussian Image', 'Median Image',
'Sobel Image', 'Binary Image', 'Dilation Image', 'Erosion Image', 'Dilation2 Image']
images = [lenna_img, GrayImage, Gaussian,
Median, Sobel, Binary,
Dilation, Erosion, Dilation2]
for i in xrange(9):
plt.subplot(3,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
輸出結果如下圖所示,可以看到輪廓區域已經被提取出來,接下來開始有選擇的進行獲取。
五、指定演算法選擇車牌區域
該部分程式碼膨脹和腐蝕略有區別,採用closed變數實現。同時獲取最理想的區域,完整程式碼如下所示:
#encoding:utf-8
#BY:Eastmount CSDN 2018-08-06
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
imagePath = '10.jpg'
img = cv2.imread(imagePath)
#opencv預設的imread是以BGR的方式進行儲存的
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度影象處理
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(u"讀入lenna圖的shape為", GrayImage.shape)
#直方圖均衡化
#equ = cv2.equalizeHist(gray)
#高斯平滑 去噪
Gaussian = cv2.GaussianBlur(GrayImage, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
#Gaussian = cv2.GaussianBlur(GrayImage, (9, 9),0)
#中值濾波
Median = cv2.medianBlur(Gaussian, 5)
#Sobel運算元 XY方向求梯度 cv2.CV_8U
x = cv2.Sobel(Median, cv2.CV_32F, 1, 0, ksize = 3) #X方向
y = cv2.Sobel(Median, cv2.CV_32F, 0, 1, ksize = 3) #Y方向
#absX = cv2.convertScaleAbs(x) # 轉回uint8
#absY = cv2.convertScaleAbs(y)
#Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
gradient = cv2.subtract(x, y)
Sobel = cv2.convertScaleAbs(gradient)
cv2.imshow('dilation2', Sobel)
cv2.waitKey(0)
#二值化處理 周圍畫素影響
blurred = cv2.GaussianBlur(Sobel, (9, 9),0) #再進行一次高斯去噪
#注意170可以替換的
ret, Binary = cv2.threshold(blurred , 170, 255, cv2.THRESH_BINARY)
cv2.imshow('dilation2', Binary)
cv2.waitKey(0)
# 膨脹和腐蝕操作的核函式
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7))
# 膨脹一次,讓輪廓突出
Dilation = cv2.dilate(Binary, element2, iterations = 1)
# 腐蝕一次,去掉細節
Erosion = cv2.erode(Dilation, element1, iterations = 1)
# 再次膨脹,讓輪廓明顯一些
Dilation2 = cv2.dilate(Erosion, element2,iterations = 3)
cv2.imshow('Dilation2 ', Dilation2)
cv2.waitKey(0)
##########################################
#建立一個橢圓核函式
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25))
#執行影象形態學, 細節直接查文件,很簡單
closed = cv2.morphologyEx(Binary, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
cv2.imshow('erode dilate', closed)
cv2.waitKey(0)
##########################################
#顯示圖形
titles = ['Source Image','Gray Image', 'Gaussian Image', 'Median Image',
'Sobel Image', 'Binary Image', 'Dilation Image', 'Erosion Image', 'Dilation2 Image']
images = [lenna_img, GrayImage, Gaussian,
Median, Sobel, Binary,
Dilation, Erosion, closed]
for i in xrange(9):
plt.subplot(3,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
cv2.imshow('Gray', GrayImage)
cv2.waitKey(0)
"""
接下來使用Dilation2圖片確定車牌的輪廓
這裡opencv3返回的是三個引數
引數一:二值化影象
引數二:輪廓型別 檢測的輪廓不建立等級關係
引數三:處理近似方法 例如一個矩形輪廓只需4個點來儲存輪廓資訊
"""
(_, cnts, _) = cv2.findContours(closed.copy(),
cv2.RETR_LIST, #RETR_TREE
cv2.CHAIN_APPROX_SIMPLE)
#畫出輪廓
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
print c
#compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
print 'rectt', rect
Box = np.int0(cv2.boxPoints(rect))
print 'Box', Box
#draw a bounding box arounded the detected barcode and display the image
Final_img = cv2.drawContours(img.copy(), [Box], -1, (0, 0, 255), 3)
cv2.imshow('Final_img', Final_img)
cv2.waitKey(0)
輸出結果如下圖所示,可以看到車牌被選中了。
參考文獻推薦大家學習三位大神的作品:
https://www.jianshu.com/p/fcfbd3131b84
https://blog.csdn.net/sinat_36458870/article/details/78825571
https://blog.csdn.net/sumkee911/article/details/79435983
當然還有很多優化和提升的地方,作者自己也還在不斷學習中,希望大家對這篇文章感興趣,同時最近的Python新書也宣傳下,大家一起進步。基礎性文章,如果文章中有錯誤或不足之處還請海涵。
本書主要包括上下兩冊:
《Python網路資料爬取及分析從入門到精通(爬取篇)》
《Python網路資料爬取及分析從入門到精通(分析篇)》
(By:Eastmount 2018-08-06 深夜11點 http://blog.csdn.net/eastmount/ )
相關文章
- sobel運算元,matlab實現Matlab
- [Python影象處理] 五.影象融合、加法運算及影象型別轉換Python型別
- Python 影像處理 OpenCV (12): Roberts 運算元、 Prewitt 運算元、 Sobel 運算元和 Laplacian 運算元邊緣檢測技術PythonOpenCV
- 基於OpenCV的車牌識別(Sobel、顏色定位)OpenCV
- [Python影象處理] 三.獲取影象屬性、興趣ROI區域及通道處理Python
- [Python影象處理] 九.形態學之影象開運算、閉運算、梯度運算Python梯度
- 車牌識別系統、車牌識別整合、車牌識別介面
- 影像處理領域的加速運算元收集
- 影象識別及處理相關資料集介紹
- [Python影象處理] 十.形態學之影象頂帽運算和黑帽運算Python
- [Python影象處理] 一.影象處理基礎知識及OpenCV入門函式PythonOpenCV函式
- 車牌識別
- 移動端的車牌識別如何實現
- 車牌識別相機及簡介
- 車牌識別SDK
- PaddlePaddle車牌識別實戰和心得
- JavaScript 資料處理 - 運算元組JavaScript
- 車牌識別系統
- 智慧城市車牌識別
- 車牌識別資料
- 車牌識別助力“智慧停車”
- [Python影象處理] 七.影象閾值化處理及演算法對比Python演算法
- CANN運算元:利用迭代器高效實現Tensor資料切割分塊處理
- 車牌識別字元模板庫字元
- 智慧車牌識別相機
- 車牌識別一體機在智慧領域的應用
- python opencv識別藍牌車牌號 之 取出車牌號 (1/3)PythonOpenCV
- [譯]計算機如何高效識別影象?計算機
- 影象二值化(python+opencv)PythonOpenCV
- 車牌識別服務-JAVA+ONNX版本,支援全型別的車牌Java型別
- 嵌入式dsp車牌識別
- 影象處理之影象增強
- python示例 呼叫影象識別服務識別影象Python
- Python 影像處理 OpenCV (13): Scharr 運算元和 LOG 運算元邊緣檢測技術PythonOpenCV
- 2021車牌識別相機技術發展現狀
- 實戰 | 用Python做影象處理(一)Python
- Python 影像處理 OpenCV (9):影像處理形態學開運算、閉運算以及梯度運算PythonOpenCV梯度
- 移動端車牌識別的應用