wpf esc key 检测不到_自己动手丰衣足食!想让你的车能检测和识别物体?试试这个实验...
全文共7733字,預計學習時長23分鐘
來源:Pexels
幾個月前,筆者有一些想法,想讓自己的車能檢測和識別物體。筆者之所以有如此想法,主要是因為已經見識了特斯拉的能力,雖然并不想馬上買一輛特斯拉(不得不說,Model 3看起來一天比一天誘人),但筆者認為應該嘗試實現自己的夢想。
所以,筆者實施了這個想法。
動圖來自結果的預測視頻。
下文記錄了項目中的每個步驟。如果只想看到檢測器運行的視頻或者GitHub鏈接,請跳到底部。
第一步,確定項目范圍
起初,筆者思考了這樣一個系統應該有什么能力。如果說筆者這輩子學到了什么,那就是從小范圍開始永遠是最好的策略:小步走。所以,除了車道保持任務(每個人都已經做過),筆者只是想在駕駛時簡單地識別車牌。此識別過程包括兩個步驟:
1、檢測車牌。
2、識別每個車牌邊框內的文字。
筆者認為,如果能做到這一點,那么繼續進行其他任務應該是相當容易的(比如確定碰撞風險、距離等)。甚至可以創建一個向量空間來表示環境,這就十分炫酷了。
在過于擔心細節之前,筆者需要:
· 一個機器學習模型,將未標記圖像作為輸入并檢測車牌。
· 一些硬件。粗略地說,需要一個連接到一個或多個攝像機的計算機系統來查詢模型。
首先著手構建對象檢測的正確模型。
第二步,選擇正確模型
經過仔細研究,決定采用以下機器學習模型:
1. YOLOv3——這是迄今為止速度最快的模型,具有可與其他先進模型相媲美的映射。這個模型是用來檢測對象的。
2. CRAFT文本檢測器——用于檢測圖像中的文本。
3. CRNN ——一個循環的CNN(卷積神經網絡)模型。它必須進行循環,因為它需要將檢測到的字符按正確的順序組成單詞。
這三個模型如何協同?操作流程如下:
1. 首先,YOLOv3模型在攝像頭接收到的每一幀中檢測每個車牌的邊框。不建議預測的邊框非常精確,超過檢測到的對象的范圍較為合適。如果范圍太狹窄,那么可能會影響后續進程的性能。這與下面的模型是并行不悖的。
2. CRAFT文本檢測器從YOLOv3接收裁剪后的車牌。如果裁剪的幀太狹窄,那么很有可能會漏掉車牌的部分文字,導致預測失敗。但當邊框較大時,可以讓CRAFT模型檢測字的位置。這可以非常精確地預測每個字的位置。
3. 最后,可以將CRAFT中每個單詞的邊框輸入CRNN模型來預測實際單詞。
有了基本的模型架構,接下來可以解決硬件了。
第三步,設計硬件
當筆者知道自己需要一些簡單的東西時,便想起了舊愛:樹莓派。它有足夠的計算能力來用合適的幀數對幀進行預處理,它也有Pi Camera。Pi Camera是樹莓派的攝像機系統。它有一個非常棒的存儲庫,而且非常成熟。
至于互聯網接入,可以只用一個EC25-E來實現4G接入,也有來自筆者曾經的項目的一個GPS模塊嵌入。
筆者決定從外殼開始。把它掛在汽車的后視鏡上應該會很好用,所以最后設計了一個雙組件支撐結構:
1. 后視鏡一側,樹莓派+GPS模塊+4G模塊。可以查看筆者關于EC25-E模塊的文章,看看筆者對GPS和4G天線的選擇。
2. 在另一側,將用一個球關節臂來支撐Pi Camera進行定位。
這些支架/外殼將用筆者信任的Prusa i3 MK3S 3D打印機打印。
圖1—樹莓派+4G/GPS防護外殼
圖2—用球關節支撐Pi Camera進行定位
圖1和圖2顯示了實施時的結構。請注意,C型夾持器是可插拔的,所以已經打印的支架不附帶樹莓派的外殼和Pi Camera的支架。它們有一個插座,可將支架插入其中。如某一個讀者決定復制該項目,這是非常有用的。只需調整支架,使其適應汽車后視鏡。目前,筆者車上(是一臺路虎神行者)的夾持器功能良好。
圖3—PiCamera支架結構的側視圖
圖4—Pi Camera支架結構以及樹莓派夾持器的正視圖
圖5—對攝像機視野的預測
圖6—4G/GPS模塊、Pi Camera和樹莓派的嵌入式系統的特寫照片
顯然,這些需要一些時間來建模。筆者需要幾次迭代來使結構更加堅固。筆者在200微米的層高使用了PETG材料。PETG能夠在80-90攝氏度中運行,并且抗紫外線輻射性很強,雖然不如ASA。
第四步,訓練模型
一旦有了硬件,就開始訓練模型。
不出所料,最好不要自己重新創造,而是盡可能重復使用別人的。這就是遷移學習的全部內容——利用來自其他非常龐大的數據集的見解。筆者幾天前在這篇文章中讀到了關于遷移學習的一個例子。文中談到了一個哈佛醫學院的附屬團隊,該團隊能夠微調一個模型,“從胸片中預測長期死亡率,包括非癌癥死亡”。他們只有5萬張標記圖像的小數據集,但是使用的預訓練模型(Inception-v4)是在大約1400萬張圖像上訓練的。他們只花了不到一小部分的原始模型所需的訓練成本(時間和金錢方面),而且已經達到了相當高的精確度。
筆者也打算這么做。
YOLOv3
筆者在網上尋找預先訓練過的車牌模型,沒有最初預期的那么多,但找到了一個在大約3600張車牌圖像上訓練過的模型。它并不多,但也比什么都沒有強,而且除此之外,它也是在Darknet的預訓練模型上訓練的,可以使用。
而且因為筆者已經有了一個可以錄制的硬件系統,所以筆者決定在鎮上駕駛幾個小時,收集幀,來對上述模型進行微調。
筆者使用VOTT對收集到的幀進行注釋(當然還有車牌)。最后創建了一個由534幅圖像組成的小數據集,其中帶有標記的車牌邊框。
然后筆者找到了YOLOv3網絡在Keras上的應用。用它來訓練數據集,然后把筆者的模型再放到這個庫中,這樣其他人也可以使用它。筆者在測試集上得到的映射是90%,在如此小的數據集上能有如此表現已經很不錯了。
CRAFT以及CRNN
在無數次嘗試尋找一種好的網絡來識別文本之后,筆者偶然發現了keras-ocr,它是CRAFT和CRNN包的一個靈活版本。而且它還附帶了他們預先訓練好的模型。那太棒了。筆者決定不對模型進行微調,讓它們保持原樣。
最重要的是,用keras-ocr預測文本非常簡單。基本上只是幾行代碼。可以去他們的主頁看看是怎么做的。
第五步,將筆者的車牌部署到檢測器模型
可以采用兩種主要的模型部署方法:
1、在本地處理所有推理。
2、在云端處理所有推理。
這兩種方法都有一些困難。第一種方法意味著要有一個龐大的“大腦”計算機系統,這很復雜而且昂貴。第二個挑戰涉及延時和基礎設施,特別是用GPU進行推理。
筆者在研究中,偶然發現了一個叫做cortex的開源項目。這是相當新鮮的,但它作為人工智能開發工具下一步的進化肯定是有一定意義的。
從根本上說,cortex是一個用于將機器學習模型部署為一鍵切換的生產web服務的平臺。這意味著筆者可以專注于應用程序,剩下的事情交給cortex來管理。在本例中,它完成了AWS上的所有配置,而筆者要做的唯一一件事就是使用模板模型來編寫預測器。更牛的是,每個模型只要寫幾十行即可。
這是GitHub庫中cortex在終端中的作用。除了美麗和簡單,筆者想不出還能用什么詞來形容:
圖源: Cortex GitHub
由于這個計算機視覺系統不是自動駕駛使用的,延遲對筆者來說就不那么重要了,筆者可以用cortex來解決這個問題。如果它是自動駕駛系統的一部分,那么使用通過云提供商提供的服務就不是一個好主意,至少目前不是。
使用cortex部署機器學習模型僅需以下步驟:
1. 確定cortex.yaml文件,這是API的配置文件。每個API將處理一種類型的任務。筆者指定的yolov3 API用于檢測指定幀上車牌的邊框,而crnn API用于通過CRAFT文本檢測器和CRNN來預測車牌。
2. 確定每個API的預測器。基本上,就是在cortex中定義一個特定類的預測法以接收一個有效負載(所有檢測的部分已經由平臺處理),使用有效負載預測結果,然后返回預測。就這么簡單!
在不深入討論筆者是如何完成這一工作的具體細節的情況下(為了保持文章的適當長度),這里有一個經典虹膜數據集的預測器示例。cortex實現這兩個API的鏈接可以在這里的存儲庫中找到,這個項目的所有其他資源都在本文末尾。
#predictor.pyimport boto3import picklelabels = ["setosa", "versicolor","virginica"]class PythonPredictor: def __init__(self, config): s3 = boto3.client("s3") s3.download_file(config["bucket"], config["key"],"model.pkl") self.model =pickle.load(open("model.pkl", "rb")) def predict(self, payload): measurements = [ payload["sepal_length"], payload["sepal_width"], payload["petal_length"], payload["petal_width"], ] label_id =self.model.predict([measurements])[0] return labels[label_id]然后做一個預測,只需使用curl,就像這樣
curl http://***.amazonaws.com/iris-classifier -X POST -H "Content-Type:application/json" -d '{"sepal_length": 5.2,"sepal_width": 3.6, "petal_length": 1.4,"petal_width": 0.3}'做出的預測就像這個“Setosa”。非常簡單!
第六步,開發客戶端
通過cortex完成部署,筆者可以繼續設計客戶端——這是比較棘手的部分。
筆者想出了以下結構:
1. 以30幀每秒的速度從Pi Camera以相當高的分辨率(800x450或480x270)收集幀,并將每個幀推入公用隊列。
2. 在一個單獨的進程中,筆者將從隊列中取出幀,并將它們分發給不同工作線程。
3. 每個工作線程(或筆者所稱的推理線程)都將向cortex API發出API請求。首先,向yolov3API發出一個請求,然后,如果檢測到任何車牌,則向crnn API發出另一個帶有一批裁剪過的車牌的請求。作出的響應將包含文本格式的預測車牌。
4. 將每個檢測到的車牌(有或無識別的文本)推送到另一個隊列,最終將其廣播到瀏覽器頁面。同時,還將車牌預測推送到另一個隊列,以便稍后將它們保存到磁盤(csv格式)。
5. 廣播隊列將接收一串無序幀。它的用戶的任務是在每次向客戶端廣播新幀時將它們放在一個非常小的緩沖區中(只有幾個幀大小),從而重新排序它們。這個用戶正在另一個進程上單獨運行。該用戶還必須嘗試將隊列上的大小保持在指定值,以便幀能夠以一致的幀數(即30幀每秒)顯示。顯然,如果隊列大小減少,那么幀數就會成比例減少,反之亦然,當隊列大小增加時,幀數也會成比例增加。最初,筆者想實現一個滯后函數,但筆者認為它會給工作流造成極大影響。
6. 同時,主進程中會有另一個線程運行,從另一個隊列和GPS數據中提取預測。當客戶端接收到終止信號時,預測、GPS數據和時間也轉存到csv文件中。
下圖是客戶端與AWS上的云API相關的流程圖。
圖7——cortex提供的云API相關的客戶端流程圖
在本例中,客戶端是樹莓派,推理請求發送到的云API是由AWS(Amazon Web Services)上的cortex提供的。
客戶端的源代碼也可以在其GitHub 存儲庫中進行查看。
必須克服的一個困難是4G的帶寬。最好降低此應用程序所需的帶寬,以減少可能的問題或對可用數據的過度使用。筆者決定在Pi Camera上使用非常低的分辨率:480x270(可以使用小分辨率,因為Pi Camera的視野非常窄,所以仍然可以很容易地識別車牌)。然而,即使在該分辨率下,幀的JPEG在10兆比特處為約100千字節。乘以30幀/秒,得到3000千字節,大約是24兆字節/秒,這還不包括HTTPoverhead——這是一個很大的數目。
筆者采用了以下策略:
· 將寬度降至416像素,這正是YOLOv3模型調整圖像大小的結果。尺寸保持完好。
· 將圖像轉換為灰度。
· 移除圖像頂部45%的部分。一般認為車牌不會出現在車架的頂部,因為汽車不會飛起來,對吧?從筆者觀察到的情況來看,剪掉45%的圖像并不會影響預測器的性能。
· 再次將圖像轉換為JPEG,但質量較低。
得到的框架大小約為7-10KB,非常好。這相當于2.8 兆字節/秒。但是算上所有的overhead,它大約是3.5兆字節/秒(也包括響應)。
對于crnn API,裁剪后的車牌根本不需要太多,即使不用壓縮技巧。每一部分大約為2-3千字節。
總而言之,要以30幀/秒的速度運行,推理API所需的帶寬約為6兆字節/秒。這個數字可以接受。
結論
這確實行之有效!
上述是通過cortex運行推理的實時示例。筆者需要大約20個配備GPU的實例才能順利運行。根據集群的延遲,可能需要更多或更少的實例。從捕獲幀到廣播到瀏覽器窗口之間的平均延遲約為0.9秒,而且推理還可以更深入,這真是太神奇了。
文本識別部分可能不是最好的,但它至少證明了這一點——通過提高視頻的分辨率,或者通過縮小攝像機的視野,或者通過微調,它可以精確得多。
高GPU可以通過優化來減少。例如,轉換模型以使用混合/全半精度(FP16/BFP16)。一般來說,使用混合精度的模型對精度的影響最小,因此并不需要進行太多的權衡。
T4和V100 GPU具有特殊的張量核心,用于在半精度類型上進行超快的矩陣乘法。在T4上,半精度運算比單精度運算的加速比約為8倍,在V100上,半精度運算比單精度運算的加速比約為10倍。這是一個數量級的差異,意味著一個已轉換為使用單精度/混合精度的模型可以少花多達8倍的時間來進行推理,而在V100上則少花十分之一的時間。
筆者還沒有轉換模型以使用單精度/混合精度,因為這超出了這個項目的范圍。就筆者而言,這只是一個優化問題。筆者最有可能在cortex 0.14版本發布時完成這項工作(如果有真正的多進程支持和基于隊列的自動縮放),這樣筆者也可以利用多進程網絡服務器。
總而言之,如果所有優化都到位,將集群的規模從20個配備GPU的實例減少到只有一個實際上是可行的。如果優化得當,甚至連一個配備GPU的實例都不用。
為了更加節約成本,在AWS上使用Elastic Inference可以減少高達75%的成本,這是一個很大的數目!形象地說,可以花一毛錢就擁有一個用于實時處理流的管道。不幸的是,目前cortex還無法支持Elastic Inference,但可以看到這一點在不久的將來就能實現,因為它已經進入了他們的視野中。參見cortexlabs/cortex/issues/618。
注意:YOLOv3和CRNN模型,可以通過在更大的數據集(大約50-100K樣本)上對其進行微調來改進。此處,幀的尺寸還可以進一步減小,以減少數據的使用,而不對精確度造成很大影響:“補償某處,以便從其他地方取走”。這與轉換所有這些模型以使用半精度類型(以及可能的Elastic Inference)相結合,可以形成一種非常有效或降低成本的推理機器。
更新
來源:Pexels
cortex的0.14版本支持網絡服務器的多進程工作器,筆者能夠將yolov3 API的GPU實例數量從8個減少到2個,將crnn API(在CRNN和CRAFT模型上運行推理)的GPU實例數量從12個減少到10個。這意味著實例的總數減少了40%,這是一個非常好的增益。所有這些實例每個都配備了單個T4 GPU和4個vCPU。
筆者發現最需要計算的模型是CRAFT模型,它是建立在約138兆的VGG-16模型之上的。請記住,由于在一次拍攝中可以有多個檢測到的車牌,因此通常需要對每一幀進行多次推理。這大大增加了對它的計算需求。從理論上講,應該取消CRAFT模型,并且改進(微調)CRNN模型,以更好地識別車牌。這樣,crnn API就可以縮小很多——只縮小到1或2個實例。
結語(包含如何將5G應用其中)
筆者看到設備開始越來越依賴云計算,特別是對于計算能力有限的邊緣設備。而且由于5G目前正在部署,理論上應該會讓云更接近這些受計算限制的設備。因此,云的影響力應該隨之增長。5G網絡越可靠、越普及,人們就越有信心將所謂的關鍵任務(比如自動駕駛汽車)的計算卸載到云端。
筆者在這個項目中學到的另一件事是,隨著在云中部署機器學習模型的流線型平臺的出現,使得更多事情變得如此容易。5年前,這將是一個相當大的挑戰:但現在,一個人就可以在相對較短的時間內做這么多事情。
資源
·查看所有3D打印夾持器的SLDPRT/SLDASM/STL/gcode。https://www.dropbox.com/sh/fw16vy1okrp606y/AAAwkoWXODmoaOP4yR-z4T8Va?dl=0
·查看本項目的客戶端實施。https://github.com/RobertLucian/cortex-license-plate-reader-client
·查看本項目的cortex實施。https://github.com/cortexlabs/cortex/tree/master/examples/tensorflow/license-plate-reader
·查看YOLOv3模型的Keras存儲庫。https://github.com/experiencor/keras-yolo3
·查看CRAFT 文本檢測器+ CRNN 文本識別器的存儲庫。https://github.com/faustomorales/keras-ocr
·查看歐洲車牌數據集(由筆者的Pi Camera捕獲的534個樣本組成)。https://github.com/RobertLucian/license-plate-dataset
·查看可以找到Keras(License_Plate.h5)和SavedModel(YOLOv3文件夾/zip)格式的YOLOv3模型。https://www.dropbox.com/sh/4ltffycnzfeul01/AACe85GoIzlmjEnIhuh5JQPma?dl=0
留言點贊關注
我們一起分享AI學習與發展的干貨
如轉載,請后臺留言,遵守轉載規范
總結
以上是生活随笔為你收集整理的wpf esc key 检测不到_自己动手丰衣足食!想让你的车能检测和识别物体?试试这个实验...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小白也能看懂的缓存雪崩、穿透、击穿
- 下一篇: java 可选参数_超干货详解:kotl