<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用OpenCV搭建違章停車檢測系統(tǒng)

          共 3765字,需瀏覽 8分鐘

           ·

          2022-02-27 11:31

          點(diǎn)擊下方AI算法與圖像處理”,一起進(jìn)步!

          重磅干貨,第一時(shí)間送達(dá)

          各位小伙伴大家好,今天將會(huì)帶領(lǐng)大家一起學(xué)習(xí)如何搭建一個(gè)違章停車檢測系統(tǒng)。需要重點(diǎn)說明的是,今天使用的邏輯和判定條件比較難,尤其是他的編程實(shí)現(xiàn)。不過小伙伴不要怕,我們提供了項(xiàng)目的開源代碼,具體鏈接如下:

          https://github.com/hasantha-nirmal/Traffic_Violation_Detection_Yolov4_Deep-Sort


          接下來我們將詳細(xì)介紹如何實(shí)現(xiàn)這個(gè)系統(tǒng)


          首先,我們需要簡要了解一下這個(gè)項(xiàng)目中的停車違章檢測是什么意思。為了介紹方便,我們將穿插使用學(xué)術(shù)術(shù)語和生活用語。想象一下,我們有一個(gè)感興趣的區(qū)域也可以稱為某個(gè)地方,車輛不應(yīng)該停放在那里。但是,如果車輛只是停在那里一會(huì)兒,我們也不能將其是為為違章,例如馬路邊允許臨時(shí)停車的區(qū)域。如果我們正在談?wù)摰倪@個(gè)區(qū)域離道路太近,那么經(jīng)過的車輛可能會(huì)與這個(gè)感興趣的區(qū)域相交,并且會(huì)立即被視為違章。所以首先,我們必須消除這種情況。也就是首先解決臨時(shí)停車不會(huì)判定為違章的情況。最簡單的解決方案是為每輛單獨(dú)的車輛引入計(jì)時(shí)器。由此,我們可以確保車輛已經(jīng)在該限制區(qū)域內(nèi)停留了多長時(shí)間。


          采用感興趣區(qū)域作為停車位,我們只需使用一個(gè)攝像頭即可,同時(shí)這個(gè)攝像頭不僅可以同時(shí)監(jiān)控和檢測特定車輛占用該停車位的時(shí)間,還可以計(jì)算出每輛車必須支付的費(fèi)用停車場。當(dāng)然了,這需要額外的開發(fā),這里小白做過多的介紹


          我們前面說過,我們需要建立一個(gè)計(jì)時(shí)器。這個(gè)任務(wù)的難點(diǎn)是需要考慮許多車輛肯定會(huì)同時(shí)出現(xiàn),這使得任務(wù)變得比較復(fù)雜。不過也沒有關(guān)系,我們只需要為不同的車輛設(shè)置不同的計(jì)時(shí)器即可。


          接下來我們將詳細(xì)介紹如何通過代碼實(shí)現(xiàn)上述的功能。

          # Parking space coordinates; #line 113parking_co = []
          #blanked = np.zeros((658,1024), dtype=np.uint8)blanked = np.zeros((2048, 1024), dtype=np.uint8)#pts = np.array(([156, 704], [2, 893], [476, 932], [270, 708]))pts = np.array(([513, 716], [321, 943], [884, 979], [630, 701]))#blanked = np.zeros((720,1280), dtype=np.uint8)#pts = np.array(([38, 433], [95, 322], [1246, 570], [1065, 709]))cv2.fillPoly(blanked, np.int32([pts]), 255)


          上面的代碼給出了我們?nèi)绾芜x擇停車位作為我們的感興趣區(qū)域。我們首先定義了一個(gè)名為park_co的空白數(shù)組,之后創(chuàng)建了一個(gè)于圖像分辨率具有相同高度或者相同寬度的一個(gè)權(quán)威零的數(shù)組。之后選擇感興趣區(qū)域的頂點(diǎn)坐標(biāo)。在pts變量中存放我們選擇的感興趣區(qū)域的頂點(diǎn)坐標(biāo)。之后我們使用OpenCV中的fillPoly函數(shù)將感興趣區(qū)域填充上,以便于我們判斷車輛是否與感興趣區(qū)域相交。


          感興趣區(qū)域的選擇如下圖所示




          現(xiàn)在,我們有了感興趣的區(qū)域或禁止車輛停放的地方的像素的所有坐標(biāo)點(diǎn)。然后我們選取車輛的邊界框坐標(biāo)(如何識(shí)別車輛呢,可以參考小白之前的文章)。但是,這又帶來了一個(gè)問題。如果相機(jī)離這個(gè)感興趣區(qū)域太近,當(dāng)有車輛接近該區(qū)域時(shí),它的邊界框會(huì)占據(jù)非常多的坐標(biāo)點(diǎn),當(dāng)同時(shí)有車輛時(shí),必須對(duì)視頻的每一幀重復(fù)這個(gè)過程,導(dǎo)致幀率急劇下降。所以,我對(duì)這個(gè)案例提出了一個(gè)假設(shè):如果一個(gè)車輛/邊界框與這個(gè) ROI 相交,它肯定也與邊界框的底線相交。所以就像在車道線違例中一樣,而不是取車輛的所有邊界框坐標(biāo)

          bbox_bottom_line_co = list(zip(*line(*(int(bbox[0])+50,int(bbox[3])), *(int(bbox[2])-50,int(bbox[3])))))


          上面是提取底線坐標(biāo)的代碼。我們通過從線條的每一側(cè)移除 50 個(gè)像素坐標(biāo)來減少線條長度,以便更好地表示車輛。因此,該線始終停留在車輛區(qū)域內(nèi),并且不占用其周圍的任何空閑空間。


          if len(intersection(parking_co, bbox_bottom_line_co)) > 0:frame_matrix.append((str(frame_num) + class_name + str(t),(str(int(bbox[0])).zfill(4), str(int(bbox[1])).zfill(4), str(int(bbox[2])).zfill(4),str(int(bbox[3])).zfill(4))))

          想象一輛車第一次與該地區(qū)相交。當(dāng)它發(fā)生在特定幀內(nèi)的那一刻,我們立即附加該事件的幀號(hào)frame_num車輛類型(class_name),車輛跟蹤 ID(str(t))和該車輛在該幀的邊界框坐標(biāo)


          chk_index = str(frame_matrix).find(str(frame_num — 1) + class_name + str(t))


          然后立即檢查前一幀是否為同一車輛發(fā)生了相同類型的相交點(diǎn)。如果這個(gè)相交點(diǎn)是第一次發(fā)生,則不滿足這個(gè)條件,程序進(jìn)入下一幀,沒有任何進(jìn)一步的交互。但是想象一下,如果這是車輛與感興趣區(qū)域相交后的第二幀,那么會(huì)為這個(gè)chk_index變量賦一個(gè)值。


          if bool(chk_index + 1) == True:previous_bbox_co_str = str(frame_matrix)[(chk_index — 1) + len(str(frame_num — 1)) + len(class_name + str(t)) + 5:(chk_index — 1) + len(str(frame_num — 1)) + len(class_name + str(t)) + 5 + 30]

          我們首先對(duì)( chk_index+1 )的布爾值給出一個(gè)正值。設(shè)置為1的原因是,對(duì)于特定車輛,它的日志詳細(xì)信息可能從數(shù)組的最開頭開始,因此將其在數(shù)組中的放置值設(shè)置為 0。如果發(fā)生這種情況,bool(0)會(huì)使條件為 false即使它為真。如果沒有這樣的日志條目,則 chk_index僅返回 -1,當(dāng)設(shè)為?+1 時(shí),它會(huì)給出所需的 False 輸出。


          此外,當(dāng)該條件為真時(shí),將會(huì)有關(guān)于邊界框的前一幀日志詳細(xì)信息獲取到另一個(gè)名為previous_bbox_co_str的變量中。


          現(xiàn)在我們知道了車輛在當(dāng)前幀和前一幀的邊界框坐標(biāo)。由于我們一直都知道車輛一直在 ROI 中,因此我們需要確定車輛是靜止(不動(dòng))還是移動(dòng)的。這里我們聲明了一個(gè)名為immobile的新函數(shù),用于實(shí)現(xiàn)這個(gè)功能。

          # Check the immobility of vehicle #line 99def immobile(bbox, previous_bbox_str):previous_bbox0 = int(previous_bbox_str[1:5])previous_bbox1 = int(previous_bbox_str[9:13])previous_bbox2 = int(previous_bbox_str[17:21])previous_bbox3 = int(previous_bbox_str[25:29])
          total = abs(bbox[0] — previous_bbox0) + abs(bbox[1] — previous_bbox1) + abs(bbox[2] — previous_bbox2) + abs(bbox[3] — previous_bbox3)if total <= 4:return Trueelse:return False

          這里我們使用了previous_bbox_co_str作為函數(shù)的屬性,以及當(dāng)前的邊界框坐標(biāo)。我們分別計(jì)算xmin、ymin、xmax 和 ymax 值的差值,如果絕對(duì)差值小于 4,輸出 True,表示車輛是不動(dòng)的,否則輸出 False。

          需要注意,即使車輛或任何物體完全停止,YOLO 也會(huì)給出波動(dòng)的邊界框坐標(biāo)。為避免這個(gè)現(xiàn)象并使此過程穩(wěn)健,我們?cè)诖颂帉⑴卸ㄗ兞吭O(shè)置為比較高的值。該值越高,程序?qū)吔缈虻碾S機(jī)波動(dòng)就越魯棒。

          因此,如果作為車輛的函數(shù)輸出是不動(dòng)的(靜止的),那么我們需要立即檢查 cache_matrix 中是否有任何先前記錄的條目,如果沒有,我們需要加上當(dāng)前時(shí)間(t_start)和車輛類型(class_name)并跟蹤標(biāo)識(shí)(str(t))

          if str((class_name + str(t))) not in str(cache_matrix): #line 310 t_start= datetime.now()cache_matrix.append((str(t_start), class_name + str(t)))print(cache_matrix)

          之后,我們檢查車輛是否在cache_matrix中。同時(shí)還要檢查同一輛車是否也在viol_matrix中。(因?yàn)槲乙呀?jīng)將違規(guī)車輛記錄,這些車輛已經(jīng)靜止并超過了時(shí)間限制)。如果不是,我們應(yīng)立即檢索該特定車輛的t_start值并使用當(dāng)前時(shí)間檢查不同的時(shí)間。

          index = (str(cache_matrix).find(str((class_name + str(t))))) #line 318t_start_cm = str(cache_matrix)[index — 28:index — 11]t_spending = (datetime.now() — datetime.strptime(t_start_cm,‘%y-%m-%d %H:%M:%S’)).total_seconds()

          如果時(shí)間差 (t_spending) 超過時(shí)間限制,那么我們將詳細(xì)信息記錄到電子表格中,其中包括車輛第一次進(jìn)入時(shí)間 (t_start_cm)、車輛類型 (class_name) 和車輛跟蹤 ID (str(t)) . 在這種情況下,出于演示目的,我們將計(jì)時(shí)器設(shè)置為 10 秒。示例如下



          sheet.write(row_num, 0, str(t_start_cm), style) #line 328# sheet.write(row_num, 1, str(round(t_spending, 2)), style)sheet.write(row_num, 1, str(class_name ) + str(t), style)row_num += 1workbook.save('outputs/xlsx/parking/details.xls')


          然后我們必須將這輛特定車輛作為日志條目放入viol_matrix數(shù)組中,因?yàn)樵撥囕v現(xiàn)在已經(jīng)違規(guī)了。這避免了進(jìn)一步的重復(fù)和錯(cuò)誤的日志條目。然后,我們可以拍攝該違規(guī)車輛的圖像并將其保存為車輛類型,并將跟蹤 ID 作為其名稱。


          viol_matrix.append((str((class_name + str(t))))) #line 334# print(t_start_cm, t_spending, datetime.now())cropped = image.crop((int(bbox[0]), int (bbox[1]), int(bbox[2]), int(bbox[3])))cropped.save('outputs/caps_of_detections/parking/' + str(class_name) + str(t) + str(' .jpg'))


          以上基本上是我們?cè)O(shè)計(jì)的違章停車檢測系統(tǒng)的想法。為避免frame_matrix的內(nèi)存過載,每超過107 個(gè)條目使用以下函數(shù)刷新該數(shù)組。


          #Avoid buffer overflow #line 353if len(frame_matrix)>10?:frame_matrix=[]

          以上就是本文的全部內(nèi)容啦,感興趣的小伙伴們可以操練其來了!


          努力分享優(yōu)質(zhì)的計(jì)算機(jī)視覺相關(guān)內(nèi)容,歡迎關(guān)注:

          交流群


          歡迎加入公眾號(hào)讀者群一起和同行交流,目前有美顏、三維視覺計(jì)算攝影、檢測、分割、識(shí)別、NeRF、GAN算法競賽等微信群


          個(gè)人微信(如果沒有備注不拉群!
          請(qǐng)注明:地區(qū)+學(xué)校/企業(yè)+研究方向+昵稱



          下載1:何愷明頂會(huì)分享


          AI算法與圖像處理」公眾號(hào)后臺(tái)回復(fù):何愷明,即可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經(jīng)典工作的總結(jié)分析


          下載2:終身受益的編程指南:Google編程風(fēng)格指南


          AI算法與圖像處理」公眾號(hào)后臺(tái)回復(fù):c++,即可下載。歷經(jīng)十年考驗(yàn),最權(quán)威的編程規(guī)范!



          下載3 CVPR2021

          AI算法與圖像處公眾號(hào)后臺(tái)回復(fù):CVPR即可下載1467篇CVPR?2020論文 和 CVPR 2021 最新論文


          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲做受 69 | 大香蕉伊人18禁止出售借阅 | 久久精品美女 | 波多野吉衣AⅤ无码一区小说 | 夜夜夜夜撸一撸 |