找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 8009|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

基于opencv的車牌識(shí)別

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
車牌識(shí)別流程:


高斯模糊:
車牌識(shí)別中利用高斯模糊將圖片平滑化,去除干擾的噪聲對(duì)后續(xù)圖像處理的影響。
高斯模糊(GaussianBlur()),也叫高斯平滑。
周邊像素的平均值,所謂"模糊",可以理解成每一個(gè)像素都取周邊像素的平均值。
    上圖中,2是中間點(diǎn),周邊點(diǎn)都是1。"中間點(diǎn)"取"周圍點(diǎn)"的平均值,就會(huì)變成1。在數(shù)值上,這是一種"平滑化"。在圖形上,就相當(dāng)于產(chǎn)生"模糊"效果,"中間點(diǎn)"失去細(xì)節(jié)(上圖右)。顯然,計(jì)算平均值時(shí),取值范圍越大,"模糊效果"越強(qiáng)烈。

左圖分別是原圖、模糊半徑3像素、模糊半徑10像素的效果。模糊半徑越大,圖像就越模糊。從數(shù)值角度看,就是數(shù)值越平滑。
接下來(lái)的問(wèn)題就是,既然每個(gè)點(diǎn)都要取周邊像素的平均值,那么應(yīng)該如何分配權(quán)重呢?
如果使用簡(jiǎn)單平均,顯然不是很合理,因?yàn)閳D像都是連續(xù)的,越靠近的點(diǎn)關(guān)系越密切,越遠(yuǎn)離的點(diǎn)關(guān)系越疏遠(yuǎn)。因此,加權(quán)平均更合理,距離越近的點(diǎn)權(quán)重越大,距離越遠(yuǎn)的點(diǎn)權(quán)重越小。

OpenCV中函數(shù)
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT)
參數(shù)詳解:
src:輸入圖片,可以使是任意通道數(shù),該函數(shù)對(duì)通道是獨(dú)立處理的,但是深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst:輸出圖片,和輸入圖片相同大小和深度。
ksize:高斯內(nèi)核大小。ksize.width和ksize.height允許不相同但他們必須是正奇數(shù);蛘叩扔0,由參數(shù)sigma的乘機(jī)決定。
sigmaX:高斯內(nèi)核在X方向的標(biāo)準(zhǔn)方差。
sigmaY:高斯內(nèi)核在Y方向的標(biāo)準(zhǔn)方差。如果sigmaY為0,他將和sigmaX的值相同,如果他們都為0,那么他們由ksize.width和ksize.height計(jì)算得出。
borderType:用于判斷圖像邊界的模式。
1 Mat Gaussian(Mat &img) {2     Mat out;3     GaussianBlur(img, out, Size(3, 3),4         0, 0, BORDER_DEFAULT);5     return out;6 7 }
View Code
原圖:(來(lái)自百度)
  

灰度化:
在車牌識(shí)別中我們需要將圖像轉(zhuǎn)化為灰度圖像,這樣有利于后續(xù)步驟的開展,如Soble算子只能作用于灰度圖像。
灰度化,在RGB模型中,如果R=G=B時(shí),則彩色表示一種灰度顏色,其中R=G=B的值叫灰度值,因此,灰度圖像每個(gè)像素只需一個(gè)字節(jié)存放灰度值(又稱強(qiáng)度值、亮度值),灰度范圍為0-255。
Opencv中函數(shù)
void cvtColor(InputArray src,  OutputArray dst,  int code,  int dstCn=0 )
參數(shù)詳解:
src輸入圖像:8位無(wú)符號(hào)的16位無(wú)符號(hào)(cv_16uc…)或單精度浮點(diǎn)。
dst的大小和深度src.
code輸出圖像顏色空間轉(zhuǎn)換的代碼。
dstCn目標(biāo)圖像中的信道數(shù);如果參數(shù)為0,則從SRC和代碼自動(dòng)導(dǎo)出信道的數(shù)目。
1 Mat Grayscale(Mat &img) {2     Mat out;3     cvtColor(img, out, CV_RGB2GRAY);4 5     return out;6 }
View Code


Sobel算子(X方向):
車牌定位的核心算法,水平方向上的邊緣檢測(cè),檢測(cè)出車牌區(qū)域。
主要用于獲得數(shù)字圖像的一階梯度,常見的應(yīng)用和物理意義是邊緣檢測(cè)。在技術(shù)上,它是一個(gè)離散的一階差分算子,用來(lái)計(jì)算圖像亮度函數(shù)的一階梯度之近似值。在圖像的任何一點(diǎn)使用此算子,將會(huì)產(chǎn)生該點(diǎn)對(duì)應(yīng)的梯度矢量或是其法矢量。
該算子包含兩組3x3的矩陣,分別為橫向及縱向,將之與圖像作平面卷積,即可分別得出橫向及縱向的亮度差分近似值。如果以A代表原始圖像,Gx及Gy分別代表經(jīng)橫向及縱向邊緣檢測(cè)的圖像,其公式如下:


圖像的每一個(gè)像素的橫向及縱向梯度近似值可用以下的公式結(jié)合,來(lái)計(jì)算梯度的大小。


可用以下公式計(jì)算梯度方向。


在以上例子中,如果以上的角度Θ等于零,即代表圖像該處擁有縱向邊緣,左方較右方暗。

OpenCV中函數(shù):
void Sobel(InputArray src, OutputArray dst, int ddepth, int xorder, int yorder, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT )
參數(shù):
src源圖像。
dst:相同大小和相同數(shù)量的通道的目標(biāo)圖像。
ddepth:目標(biāo)圖像的深度。
xorder:階導(dǎo)數(shù)的X.
yorder:階導(dǎo)數(shù)的Y.
ksize:擴(kuò)展Sobel算子–大小。它必須是1, 3, 5,或者7。
scale計(jì)算衍生值的可選刻度因子。默認(rèn)情況下,不應(yīng)用縮放?吹絞etderivkernels()詳情。
delta :可選的delta值,在將它們存儲(chǔ)在DST之前添加到結(jié)果中。
bordertype:像素外推方法。
convertScaleAbs()——先縮放元素再取絕對(duì)值,最后轉(zhuǎn)換格式為8bit型。
1 Mat Sobel(Mat &img) { 2     Mat out; 3     Mat grad_x, grad_y; 4     Mat abs_grad_x, abs_grad_y; 5 6     //X方向 7     //Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT); 8     //convertScaleAbs(grad_x, abs_grad_x); 9     Sobel(img, img, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);10     convertScaleAbs(img, out);11 12     //Y方向13     //Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);14     //convertScaleAbs(grad_y, abs_grad_y);15     //convertScaleAbs(img, out);16 17     //合并18     //addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, out);19 20     return out;21 }
View Code


二值化:
進(jìn)一步對(duì)圖像進(jìn)行處理,強(qiáng)化目標(biāo)區(qū)域,弱化背景。
圖像的二值化,就是將圖像上的像素點(diǎn)的灰度值設(shè)置為0或255,也就是將整個(gè)圖像呈現(xiàn)出明顯的只有黑和白的視覺效果。
OpenCV中函數(shù)
double threshold(InputArray src, OutputArray dst, double thresh, double maxVal, int thresholdType)
參數(shù):
src源陣列(單通道,32位浮點(diǎn)8位)。
dst:相同大小和類型的目標(biāo)數(shù)組。
thresh門限閾值。
Maxval:最大值使用的thresh_binary和thresh_binary_inv閾值類型。
thresholdtype:閾值型,如下。
THRESH_BINARY  當(dāng)前點(diǎn)值大于閾值時(shí),取Maxval,也就是第四個(gè)參數(shù),下面再不說(shuō)明,否則設(shè)置為0
THRESH_BINARY_INV 當(dāng)前點(diǎn)值大于閾值時(shí),設(shè)置為0,否則設(shè)置為Maxval
THRESH_TRUNC 當(dāng)前點(diǎn)值大于閾值時(shí),設(shè)置為閾值,否則不改變
THRESH_TOZERO 當(dāng)前點(diǎn)值大于閾值時(shí),不改變,否則設(shè)置為0
THRESH_TOZERO_INV 當(dāng)前點(diǎn)值大于閾值時(shí),設(shè)置為0,否則不改變
1 Mat TwoValued(Mat &img) {2     Mat out;3     threshold(img, out, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);4     //threshold(img, out, 100, 255, CV_THRESH_BINARY);5 6     return out;7 }
View Code


閉操作:
閉操作可以將目標(biāo)區(qū)域連成一個(gè)整體,便于后續(xù)輪廓的提取。
閉操作可使輪廓線更光滑,但與開操作相反的是,閉操作通常消彌狹窄的間斷和長(zhǎng)細(xì)的鴻溝,消除小的空洞,并填補(bǔ)輪廓線中的斷裂。
使用結(jié)構(gòu)元素B對(duì)集合A進(jìn)行閉操作,定義為


這個(gè)公式表明,使用結(jié)構(gòu)元素B對(duì)集合A的閉操作就是用B對(duì)A進(jìn)行膨脹,然后用B對(duì)結(jié)果進(jìn)行腐蝕。

OpenCV中函數(shù)
void morphologyEx(InputArray src, OutputArray dst, int op, InputArray element, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() )
參數(shù):
src:源圖像。
dst:相同大小和類型的目標(biāo)圖像。
element內(nèi)核類型    用getStructuringElement函數(shù)得到。
OP:
可以是以下形式之一的形態(tài)學(xué)操作的類型:
morph_open -開啟操作
morph_close -閉合操作
morph_gradient -形態(tài)學(xué)梯度
morph_tophat“頂帽”
morph_blackhat -“黑帽”
iterations侵蝕和膨脹的次數(shù)被應(yīng)用。
bordertype–像素外推方法。
bordervalue–邊界值在一個(gè)恒定的邊界情況。默認(rèn)值有特殊含義。
關(guān)注前4個(gè)參數(shù)即可,后面用默認(rèn)參數(shù)。

1 Mat Close(Mat &img) {2     Mat out;3     //Mat element(5, 5, CV_8U, cv::Scalar(1));4     Mat element = getStructuringElement(MORPH_RECT, Size(17, 5));5     morphologyEx(img, out, cv::MORPH_CLOSE, element);6 7     return out;8 }
View Code


取輪廓:
將前面處理的車牌目標(biāo)區(qū)域提取出來(lái)。
相關(guān)函數(shù):
查找輪廓:
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
image輸入的 8-比特、單通道圖像. 非零元素被當(dāng)成 1, 0 象素值保留為 0 - 從而圖像被看成二值的。為了從灰度圖像中得到這樣的二值圖像,可以使用 cvThreshold, cvAdaptiveThreshold 或 cvCanny. 本函數(shù)改變輸入圖像內(nèi)容。
storage :得到的輪廓的存儲(chǔ)容器
first_contour :輸出參數(shù):包含第一個(gè)輸出輪廓的指針
header_size :如果 method=CV_CHAIN_CODE,則序列頭的大小 >=sizeof(CvChain),否則 >=sizeof(CvContour) .
mode
提取模式.
CV_RETR_EXTERNAL - 只提取最外層的輪廓
CV_RETR_LIST - 提取所有輪廓,并且放置在 list 中
CV_RETR_CCOMP - 提取所有輪廓,并且將其組織為兩層的 hierarchy: 頂層為連通域的外圍邊界,次層為洞的內(nèi)層邊界。
CV_RETR_TREE - 提取所有輪廓,并且重構(gòu)嵌套輪廓的全部 hierarchy
method :
逼近方法 (對(duì)所有節(jié)點(diǎn), 不包括使用內(nèi)部逼近的 CV_RETR_RUNS).
CV_CHAIN_CODE - Freeman 鏈碼的輸出輪廓. 其它方法輸出多邊形(定點(diǎn)序列).
CV_CHAIN_APPROX_NONE - 將所有點(diǎn)由鏈碼形式翻譯(轉(zhuǎn)化)為點(diǎn)序列形式
CV_CHAIN_APPROX_SIMPLE - 壓縮水平、垂直和對(duì)角分割,即函數(shù)只保留末端的象素點(diǎn);
CV_CHAIN_APPROX_TC89_L1,
CV_CHAIN_APPROX_TC89_KCOS - 應(yīng)用 Teh-Chin 鏈逼近算法. CV_LINK_RUNS - 通過(guò)連接為 1 的水平碎片使用完全不同的輪廓提取算法。僅有 CV_RETR_LIST 提取模式可以在本方法中應(yīng)用.
offset :
每一個(gè)輪廓點(diǎn)的偏移量. 當(dāng)輪廓是從圖像 ROI 中提取出來(lái)的時(shí)候,使用偏移量有用,因?yàn)榭梢詮恼麄(gè)圖像上下文來(lái)對(duì)輪廓做分析.
函數(shù) cvFindContours 從二值圖像中提取輪廓,并且返回提取輪廓的數(shù)目。指針 first_contour 的內(nèi)容由函數(shù)填寫。它包含第一個(gè)最外層輪廓的指針,如果指針為 NULL,則沒(méi)有檢測(cè)到輪廓(比如圖像是全黑的)。其它輪廓可以從 first_contour 利用 h_next 和 v_next 鏈接訪問(wèn)到。 在 cvDrawContours 的樣例顯示如何使用輪廓來(lái)進(jìn)行連通域的檢測(cè)。輪廓也可以用來(lái)做形狀分析和對(duì)象識(shí)別 - 見CVPR2001 教程中的 squares 樣例。該教程可以在 SourceForge 網(wǎng)站上找到。

繪制輪廓:
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, intthickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )


相關(guān)參數(shù)參考——http://www.opencv.org.cn/opencvd ... urs#cv.DrawContours

漫水填充算法:
int floodFill(InputOutputArray image, Point seed, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), ScalarupDiff=Scalar(), int flags=4 )


相關(guān)參數(shù)參考——http://www.opencv.org.cn/opencvd ... odfill#cv.FloodFill

aec379310a55b31961a2c69743a98226cefc17fc.jpg (6.65 KB, 下載次數(shù): 92)

aec379310a55b31961a2c69743a98226cefc17fc.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表