“為了忘卻的記念”---紀念即將逝去的ofo和它帶我的機器學習啟蒙作-《ofo車牌識別》研發心得01-失敗的車牌定位和識別
前不久,伴隨著ofo的退押金潮,作為曾經帶給我極大方便的ofo小黃車,也即將走到它生命的盡頭。
雖然它在商業上失敗,但對于我來說ofo帶給我是機器學習、數據挖掘、圖像處理的啟蒙之作,也是我自己第1款公開渠道獨自發布的Android APP、下載量第1款破1萬的Android APP,時隔1年多下載量去到2.5萬。
但是,這1年多來,可能自己真的運氣不好,在工作中沒有遇到圖像處理的項目,也實屬遺憾!也真心感到辜負了當時司老師的悉心培育!
借華為云MVP、云享之際,重溫這段啟蒙歲月回顧一翻。原文寫在 https://github.com/motozilog??,源代碼開放。歡迎交流^_^(QQ:780174889)
下面是正文的第1部分-失敗的汽車車牌定位和識別:
實驗材料:
1.150張包含車牌的圖片
2.用于校驗程序正確性的車牌所在位置坐標表格
實驗的目的:
1.學會使用常見的圖像預處理方法,對圖像進行處理。提取出需要的部分
實驗過程:
老師在課堂上大致說了幾個步驟:二值化→邊緣檢測→根據長寬比將車牌從圖片中摳出來。
但是實際上無數多坑。前前后后坑了一個星期才弄通。
開坑還是感謝“計算機的潛意識”寫的《EasyPR--一個開源的中文車牌識別系統》。http://www.cnblogs.com/subconscious/p/3979988.html
由于本次實驗做到中段就轉方向,中間泄及的技術細節和原理就不在本文提及。詳細將在《ofo車牌定位》一文中概述。
流程如下圖:
由于我是挑這張 京E.B8550來做,當然是符合預想。
carIdentify.m %?function?carIdentify?() clear?all; clc ? [Image_ID]?=?csvread?('Plate_Index.csv',0,0,[0,0,0,0]); ? for?i?=1:length?(Image_ID) filename=[int2str(Image_ID(i)),'.jpg']; filename img?=?imread?(['Plate_Image\',filename]); ? %高斯 a?=?imgaussfilt?(img,?3); ? %灰度化 a?=?rgb2gray?(a); ? %sobel邊緣檢測 a?=?edge?(a,?'Sobel'); %?imshow?(a); ? %開閉操作 %?開運算:去除較小的明亮區域 %?閉運算:消除低亮度值的孤立點 se?=?strel?('rectangle',[7?27]);? a?=?imclose?(a,se); ? a?=?imopen?(a,se); ? se?=?strel?('rectangle',[7?95]);? a?=?imclose?(a,se); ? se?=?strel?('rectangle',[11?3]);? a?=?imopen?(a,se); ? imwrite?(a,'imout.jpg'); ? %畫出所有的外接矩型(代碼來自MATLAB中文論壇) [l,m]?=??bwlabel?(a,8); status?=?regionprops?(l,'BoundingBox'); figure(10); imshow?(img); hold?on; for?j?=?1:m ????rectangle?('position',?status(j).BoundingBox,?'edgecolor',?'r'); end hold?off; frame?=?getframe; rec?=?frame2im(frame); imwrite(rec,['S3_Rectangle_Image\',filename]) ? %查找最接近的圖形 for?k?=?1:m %左邊距的x坐標<200的,丟棄 ????if?status(k).BoundingBox(1)?200 ????????status(k).BoundingBox(1) ????????continue %橫向尺寸少于200的,丟棄 ????elseif?status(k).BoundingBox(3)?200 ????????status(k).BoundingBox(3) ????????continue ????elseif?status(k).BoundingBox(4)?50 ????????status(k).BoundingBox(4) ????????continue ????else ????????i2?=?imcrop?(img,status(k).BoundingBox); ????????imwrite?(i2,['S4_Crop_Image\',int2str(Image_ID(i)),'_',int2str(k),'.jpg']); ????end end end
但是一但將這個程序放到150張圖片時,瞬間就雷倒了。
只有21張圖片是符合預想情況可以進行下一步的操作,其它圖片都相當難處理,各種夸張的情況都有。當然用來做高技術的研究是不錯的。但是卻缺乏實用性。
并且廣州基本上是以“粵”字頭為多,所以,干脆訓練集自己重新做。
重新制作訓練集的困惑,拍了22張車牌照片。忽然發覺一件事:別人很容易會誤解我在干嘛,別人以為我是去抓違章......汗!
突然間發覺ofo的APP寫得特爛,連個二維碼掃描都沒有。ofo車牌上的二維碼,僅僅是下載APP的鏈接(開始調研時只有6位ofo,后期7位ofo上面的二維碼就直接帶了數字)。
所以,ofo車牌識別,開工吧!
首先先調查各大應用市場的車牌識別情況,車牌識別對于android來說顯然是低頻非剛需,而市場上也己經有人做了,識別的正確率還是挺高的。
再來看看目前火爆的共享單車二大巨頭:ofo和摩拜,摩拜車上己有完整的二維碼開鎖系統,對ocr識別顯然沒有需求。但是ofo,顯然沒有為互聯網和物聯網做準備,APP中需要手工輸入車牌號碼,然后再開鎖。(調研時只有6位ofo,沒有7位ofo)
再查了一下專門針對ofo車牌進行識別的應用,目前依然沒有。
并且去拍ofo車牌比較容易:
1.ofo是停在人行道上
2.拍ofo不會被人認為是抄牌之類的誤解
3.ofo產量驚人,鋪貨是10萬臺、10萬臺那樣上線,隨便路上都可以找到
進一步分晰,ofo車牌由0~9數字組成(10種分類),遠比汽車車牌的容易得多(31個省份+24個英文字母+10個數字=65種分類)。
畢竟作為學習,而非做產品或項目,只需要明白原理就好。所以就選擇ofo。
##開發平臺、工具、語言的選擇
而開發平臺的選擇上,ofo作為移動互聯網時代下的產品,做成web或者pc端的產品也太不符合應用場景了。那就干脆做成微信公眾號、小程序、APP之類。
一開始我是想做成微信公眾號,畢竟這是低頻非剛需:拍照發到公眾號,公眾號進行識別返回結果。但是微信公眾號,顯然與自己服務器上什么都可以放上去的不同,只能做web。
讓微信公眾號將照片先發到自己服務器上,處理后再返回結果。但是公網服務器需要購買云主機并且還要申請域名,對于僅僅是做學習研究來說,付費顯然不太友好。
之后,再來看看微信小程序,微信小程序主推是線下導流,線下放置二維碼,然后下載。并且體驗了幾個小程序,有點回到5年前時android應用的感覺。限制極多,并且也是要服務器。所以只得放棄。
最后只得在APP上開發。APP雖然推廣成本極高,適配麻煩。但卻有著強大的本地化資源可用的優勢。并且OpenCV有Android版的API。而Matlab卻沒有Android版API。
再核查OpenCV,也是有腐蝕、膨脹、高斯模糊、外接矩形、svm算法。滿足開發需要。
所以移動端就采用Android+OpenCV
而剛好去圖書館時發現《OpenCV圖像處理》(ISBN: 9787111527473)一書,有書就比網上凌散的資料開坑爽多了。
所以,就先將windows版的Qt+OpenCV環境搭起來,調試沒有問題,再通過JNI接口方式,移植到Android。
而在開發windows版時還是以6位ofo為主,但是ofo的產能真的太猛,一下子就上到100萬號(太有錢了!)。所以前期做了個6位ofo車牌識別(在 "6位ofo識別" 目錄中,主要以795116)。
下面主要講解7位ofo車牌識別的過程。
數據挖掘
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。