人工智能AI面試題-5.12 做過目標檢測項目么?比如Mask R-CNN和Py
5.12 做過目標檢測項目么?比如Mask R-CNN和Python做一個搶車位神器 每逢春節(jié)過年,就要開始走親訪友了。這時候的商場、飯館也都是“人聲鼎沸”,畢竟走親戚串門必不可少要帶點禮品、聚餐喝茶。 熱鬧歸熱鬧,這個時候最難的問題可能就是怎樣從小區(qū)、商場、菜市場的人山人海里準確定位,找到一個“車位”。別慌! 一位名叫Adam Geitgey的軟件工程師、AI軟件工程博主也被“停車難”的問題困擾已久。為了讓自己能給迅速定位空車位,他用實例分割模型Mask R-CNN和Python寫了一個搶占停車位的小程序。 以下是作者以第一人稱給出的教程,enjoy。1.如何找停車位 我住在一個大都市,但就像大多數(shù)城市一樣,在這里很難找到停車位。停車場總是停得滿滿的,即使你自己有私人車位,朋友來訪的時候也很讓人煩,因為他們找不到停車位。 我的解決方法是: 用攝像頭對著窗外拍攝,并利用深度學習算法讓我的電腦在發(fā)現(xiàn)新的停車位時給我發(fā)短信。 這可能聽起來相當復雜,但是用深度學習來構建這個應用,實際上非??焖俸秃唵?。有各種現(xiàn)有的實用工具 - 我們只需找到這些工具并且將它們組合在一起。 現(xiàn)在,讓我們花幾分鐘時間用Python和深度學習建立一個高精度的停車位通知系統(tǒng)吧! 分解問題 當我們想要通過機器學習解決一個復雜的問題時,第一步是將問題分解為簡單任務的列表。然后,對于每個簡單任務,我們可以從機器學習工具箱中找尋不同的工具來解決。 通過將這些簡單問題的解決方案串起來形成框架(例如下面的思維導圖),我們將實現(xiàn)一個可以執(zhí)行復雜操作的系統(tǒng)。 以下就是我如何將檢測公共停車位的問題分解并形成流程: 機器學習模型流程的輸入是來自對著窗外的普通網(wǎng)絡攝像頭的視頻: 我們將每一幀視頻送入模型里,一次一幀。 流程的第一步是檢測視頻幀中所有可能的停車位。顯然,我們需要知道圖像的哪些部分是停車位才能檢測到哪些停車位是空的。 第二步是識別每幀視頻中所有的汽車,這樣我們可以跟蹤每輛車在幀與幀之間的位移。 第三步是確定哪些停車位上目前有汽車,哪些沒有。這需要綜合第一步和第二步的結果。??最后一步是在停車位空出來的時候發(fā)送通知。這是基于視頻幀之間的汽車位置的變化。 我們可以使用各種技術以多種不同方式完成這些步驟。構建流程的方法不是唯一的,不同的方法沒有對錯,但有不同的優(yōu)點和缺點?,F(xiàn)在讓我們來看看每一步吧! 2.檢測圖像中的停車位 以下是相機拍到的圖像: 我們需要能夠掃描該圖像并返回可以停車的區(qū)域列表,如下所示: 街區(qū)上可用的停車位 有一種偷懶的方法是手動將每個停車位的位置編入到程序中,而不是自動檢測停車位。但是如果我們移動相機或想要檢測不同街道上的停車位時,我們必須再次手動輸入停車位的位置。這太不爽了,所以讓我們找到一種自動檢測停車位的方法。 一個想法是尋找停車計費表并假設每個計費表旁邊都有一個停車位: 在圖片中檢測的停車計費表 但這種方法存在一定的問題。首先,并非每個停車位都有停車咪表 – 實際上,我們最感興趣的是找到免費停車位!其次,停車咪表的位置并不能確切地告訴我們停車位的具體位置,只能讓我們離車位更接近一點。 另一個想法是建立一個物體檢測模 型,尋找在道路上繪制的停車位斜線標記,如下所示: 留意那些微小的黃色標記,這些是在道路上繪制每個停車位的邊界。 但這種做法也很痛苦。首先,我所在城市的停車位斜線標記非常小,從遠處很難看清,電腦也難以察覺。第二,街道上到處都是各種不相關的線條和標記,所以要區(qū)分哪些線條是停車位,哪些線條是車道分隔線或人行橫道是很困難的。 每當遇到一個看似困難的問題時,請先花幾分鐘時間看看是否能夠采用不同的方式來避免某些技術難 ? 點并解決問題。到底什么是停車位呢?停車位就是車輛停留很長一段時間的地方。因此也許我們根本不需要檢測停車位。為什么我們不能只檢測那些長時間不動的車并假設它們停在停車位上? 換句話說,真正的停車位只是容納了非移動中的車輛的區(qū)域: 這里每輛車的邊框?qū)嶋H上都是一個停車位!如果我們能夠檢測到靜止的汽車,就不需要真的去檢測停車位。 因此,如果我們能夠檢測到汽車并找出哪些汽車在視頻的每幀之間沒有移動,我們就可以推斷停車位的位置。這就變得很容易了! 3.檢測圖像中的汽車 檢測視頻每幀中的汽車是一個標準的對象檢測問題。我們可以使用許多種機器學習方法來檢測圖像中的對象。以下是一些從過去到現(xiàn)在最常見的對象檢測算法: a)訓練一個HOG(梯度方向直方圖)物體探測器滑過(掃描)我們的圖像以找到所有的汽車。這種 比較古老的非深度學習方法運行起來相對較快,但它對于朝向不同方向的汽車不能很好地處理。???b)訓練CNN(卷積神經(jīng)網(wǎng)絡)物體探測器閱覽(掃描)我們的圖像,直到我們找到所有的汽車。這 種方法雖然準確,但效率不高,因為我們必須使用CNN算法多次掃描同一圖像才能找到其中的所有汽車。雖然它可以很容易地找到朝向不同方向的汽車,但它需要比基于HOG的物體探測器更多的訓練數(shù)據(jù)。 c)使用更新的深度學習方法,如Mask R-CNN,快速R-CNN或YOLO,將CNN的準確性與巧妙設計和效率技巧相結合,可以大大加快檢測過程。即使有大量訓練數(shù)據(jù)來訓練模型,這種方法的速度也相對較快(在GPU上)。 一般來說,我們希望選擇最簡單的解決方案,以最少的訓練數(shù)據(jù)完成工作,而不是最新、最花哨的算法。但在這種特殊情況下,Mask R-CNN對我們來說是比較合理的選擇,盡管它相當花哨新潮。Mask R-CNN架構的設計理念是在不使用滑動窗口方法的情況下以高計算效率的方式檢 測整幅圖像上的對象。換句話說,它運行得相當快。使用最新GPU,我們可以以每秒幾幀的速度檢測高分辨率視頻中的對象。那對于這個項目來說應該沒問題。 此外,Mask???R-CNN對每個檢測到的對象給出了大量信息。大多數(shù)對象檢測算法僅返回每個對象的邊界。但Mask R-CNN不僅會給我們每個對象的位置,還會給我們一個對象輪廓(或概述),如下所示: 為了訓練Mask??R-CNN,我們需要大量的包含我們想要檢測的對象的圖像。我們可以去拍攝汽車照片并檢測這些照片中的所有汽車,但這需要幾天的工作。幸運的是,汽車是許多人想要檢測的常見物體, 因此已經(jīng)有不少汽車圖像的公共數(shù)據(jù)集。 ? 其中一個名為COCO (Common Objects in Context)的流行數(shù)據(jù)集,其中包含標注了對象輪廓的圖像。在此數(shù)據(jù)集中,有超過12,000張做了標注的汽車圖像。以下是COCO數(shù)據(jù)集中的其中一張: ? 這個數(shù)據(jù)集非常適合訓練Mask R-CNN模型。 等等,還有更好的事!由于太多人使用COCO數(shù)據(jù)集構建對象檢測模型,很多人已經(jīng)完成并共享了他們的結果。因此,我們可以從預先訓練好的模型開始,而無需訓練我們自己的模型,這種模型可以即插即用。對于這個項目,我們將使用來自Matterport的大型開源Mask??R-CNN實現(xiàn)項目,它自帶預先訓練的模型。 旁注:不要害怕訓練一個定制的Mask??R-CNN目標探測器!注釋數(shù)據(jù)是很費時,但并不難。如果我們在攝像頭拍攝的圖像上運行預先培訓過的模型,就會得到如下的結果: 在我們的圖像上,識別出了COCO數(shù)據(jù)集中的默認對象-汽車、人、交通燈和一棵樹。 我們不僅能識別汽車,還能識別交通燈和人。幽默的是,其中一棵樹被識別成一個“盆栽植物”。對于圖像中檢測到的每一個物體,我們從Mask R-CNN模型中都會得到以下四個數(shù)據(jù): 1.檢測到的對象類型(以整數(shù)形式表現(xiàn))。經(jīng)過預先訓練的COCO模型知道如何檢測80種不同的常見物??體,如汽車和卡車。這是80種的常見物體的完整清單https://gist.github.com/ageitgey/ b143ee809bf08e4927dd59bace44db0d 。?????????????????????????????????????????2.目標檢測的置信度得分。數(shù)值越高,模型就越確定它正確地識別了對象。 3.圖像中對象的邊界框,以X/Y像素位置表現(xiàn)。 4.位圖圖層告訴我們邊界框中的哪些像素是對象的一部分,哪些不是。通過圖層數(shù)據(jù),我們還可以計??算出對象的輪廓。 下面是使用Matterport’s??Mask??R-CNN中的預培訓模型和OpenCV共同實現(xiàn)汽車邊界框檢測的Python代碼: 當您運行該代碼時,會看到圖像上每輛被檢測到的汽車周圍都有一個邊框,如下所示: ? ? 被檢測到的每輛汽車周圍都有一個綠色的邊框。 您還可以在控制臺中查看每個被檢測到的汽車的像素坐標,如下所示: Cars found in frame of video: Car: [492 871 551 961] Car: [450 819 509 913] Car: [411 774 470 856] 有了這些數(shù)據(jù),我們已經(jīng)成功地在圖像中檢測到了汽車??梢赃M行下一步了 4. 檢測空車位 我們知道圖像中每輛車的像素位置。通過連續(xù)查看多幀視頻,我們可以很容易地確定哪些車輛沒有移動,并假設這些區(qū)域是停車位。但我們?nèi)绾螜z測汽車何時離開停車位呢? 主要問題是,我們的圖像中汽車的邊界框有部分重疊: 即使對于不同停車位的汽車,每輛車的邊界框也有一點重疊。 因此,如果我們假設每一個邊界框中的都代表一個停車位,那么即使停車位是空的,這個邊界框也可能有一 部分包含了其他停車位的汽車,如下圖所示: 即使停車位是空的,邊界框仍然包含了其他停車位的汽車。 如果我們等到所有的汽車都離開了停車位才通知用戶,那么通知的時機將會很晚,因為圖像中汽車的邊界框之間會有一點重疊。而如果我們在每次檢測到汽車移動時就通知用戶,那么我們將會因為假陽性(即錯誤地通知用戶車位空了)而打擾到用戶。解決辦法是,我們可以繼續(xù)跟蹤在我們的連續(xù)幀圖像中檢測到的每輛車,并在汽車離開車位時通知用戶。但我們不想做重復工作!如果一輛車在兩幀圖像之間的位置幾乎沒有變化,那么它可能只是因為相機震動或者因為幀之間的一些微小不一致而輕微變化了一下。在這種情況下,我們不希望通知用戶車位變空了,因為它只是因為錯誤識別的噪音而輕微變化。 要解決這個問題,我們可以簡單地添加一個“信心閾值”。也就是說,如果車輛在兩幀之間移動的像素數(shù)量超過某個閾值,我們才會認為它已經(jīng)離開了車位。 這種方法有一個缺點,即它可能會錯過車輛的移動,因為如果一輛車在兩幀之間移動得太快,我們可能會錯過它。但是這種方法可以減少錯誤報警的次數(shù),使系統(tǒng)更加可靠。這就是我們?nèi)绾螜z測到車位何時變?yōu)榭盏姆椒ǖ木琛?5. 通知用戶 最后一步是通知用戶車位已經(jīng)變?yōu)榭铡R坏┪覀儥z測到車輛已經(jīng)離開了車位,我們就可以使用各種方式來通知用戶。一種簡單的方法是通過短信發(fā)送通知??梢允褂酶鞣NAPI和庫來發(fā)送短信,具體取決于您所在地區(qū)的服務提供商。這里是一個使用Python發(fā)送短信通知的示例代碼,您可以根據(jù)自己的需求進行修改: import smtplib from email.mime.text import MIMEText def send_notification(message): ??# 配置您的電子郵件服務器 ??smtp_server = "smtp.example.com" ??smtp_port = 587 ??smtp_username = "your_username" ??smtp_password = "your_password" ??# 配置收件人信息 ??to_email = "recipient@example.com" ??# 創(chuàng)建電子郵件消息 ??msg = MIMEText(message) ??msg["Subject"] = "Parking Space Available" ??msg["From"] = "your_email@example.com" ??msg["To"] = to_email ??# 連接到電子郵件服務器并發(fā)送消息 ??server = smtplib.SMTP(smtp_server, smtp_port) ??server.starttls() ??server.login(smtp_username, smtp_password) ??server.sendmail("your_email@example.com", to_email, msg.as_string()) ??server.quit() # 車位變?yōu)榭諘r發(fā)送通知 send_notification("Parking space is now available!") 這是一個非?;镜氖纠?,可以根據(jù)自己的需求進行擴展和修改。 另一種通知用戶的方式是通過移動應用程序或Web界面。您可以構建一個簡單的用戶界面,顯示可用的停車位,并在停車位變?yōu)榭諘r更新界面。對于移動應用程序,您可以使用開發(fā)工具,如React Native或Flutter,來構建跨平臺應用程序。對于Web界面,您可以使用前端框架,如React或Vue.js,來構建用戶界面。 總結 通過使用深度學習模型Mask R-CNN,您可以構建一個高精度的停車位檢測系統(tǒng),該系統(tǒng)可以檢測圖像中的停車位和汽車,并通知用戶停車位何時變?yōu)榭?。這個項目需要大量的圖像數(shù)據(jù)來訓練模型,以及一些基本的編程技能來實現(xiàn)檢測和通知功能。但一旦完成,它可以極大地簡化尋找停車位的過程,使您的生活更加輕松。希望這個教程能夠幫助您入門深度學習和計算機視覺,并啟發(fā)您構建自己的智能應用程序!