作者|Hitesh Valecha
編譯|VK
來源|Towards Data Science

在本教程中,我們將學習如何使用計算機視覺和影像處理來檢測汽車是否在路上變道,
你一定聽說過使用Opencv haar cascade可以檢測人臉、眼睛或汽車、公共汽車等物體?這次讓我們用這個簡單的檢測方法來構建一些很酷的東西,
1.資料集
在本教程中,道路上汽車的視頻檔案被用作資料集,此外,我們可以使用影像資料集檢測影像中的車輛,但在這里,當車輛變道時,我們會用彈出視窗發出警報,因此對于這些動態資訊,視頻輸入更為可行,
2.輸入
我們使用OpenCV的haar cascade來檢測汽車的坐標,輸入是道路上汽車的視頻檔案
cascade_src = 'https://www.cnblogs.com/panchuangai/p/cascade/cars.xml'
video_src = 'https://www.cnblogs.com/panchuangai/p/dataset/cars.mp4'
cap = cv2.VideoCapture(video_src)
car_cascade = cv2.CascadeClassifier(cascade_src)
cv2.VideoCapture()方法用于捕獲輸入的視頻,一個視頻通常是每秒25幀影像(fps),在捕獲到輸入后,回圈提取幀,并利用haar cascade檢測,在回圈中圍繞汽車繪制一個矩形,以獲得一致性,同時對捕獲的幀執行其他操作,
while(1):
# 獲取每一幀
_, frame = cap.read()
cars = car_cascade.detectMultiScale(frame, 1.1, 1)
for (x,y,w,h) in cars:
roi = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2) #感興趣區域
在OpenCV中使用BGR而不是RGB,因此(0,0,255)將在汽車上繪制一個紅色矩形,而不是藍色,

3.影像處理
我們使用幀,但是如果幀的解析度非常高,它將減慢執行的操作,此外,幀包含噪聲,可以使用模糊來減少,這里使用高斯模糊,
現在,讓我們看看一些影像處理的概念
3.1 HSV框架
在這篇文章中,我們使用從cv2.VideoCapture()捕獲的幀中獲取HSV幀,僅突出顯示車輛轉彎的點,并遮住剩余的道路和在道路上直線行駛的車輛,設定上限和下限以定義HSV中的顏色范圍,以查看汽車變道的點,并用作幀的掩碼,下面是用于獲取此資訊的代碼片段-
# 使用模糊消除視頻幀中的噪聲
frame = cv2.GaussianBlur(frame,(21,21),0)
# 轉換BGR到HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 在HSV中定義顏色范圍,以查看車輛改變角度的點
lower_limit = np.array([0,150,150])
upper_limit = np.array([10,255,255])
# HSV影像限制閾值
mask = cv2.inRange(hsv, lower_limit, upper_limit)
3.2腐蝕和膨脹
腐蝕和膨脹是用于影像處理的兩種基本形態學操作,腐蝕算子對核函式的區域有區域最小值的影響,核函式是模板或掩碼,腐蝕是用來減少影像中的斑點噪聲,膨脹是影像與核的卷積,它具有區域最大算子的作用,當像素被添加到影像中平滑物體的邊界時,應用膨脹來恢復一些丟失的區域,
從HSV幀的第一步生成的掩碼現在用基本的形態學操作(腐蝕和擴張)來處理,生成的幀是通過將幀和掩碼之間的按位與運算得到ROI(感興趣區域),
kernel = np.ones((3,3),np.uint8)
kernel_lg = np.ones((15,15),np.uint8)
# 被稱為腐蝕的影像處理技術用于降噪
mask = cv2.erode(mask,kernel,iterations = 1)
# 稱為膨脹的影像處理技術,用來恢復失去的部磁區域
mask = cv2.dilate(mask,kernel_lg,iterations = 1)
# 除了感興趣的區域,其他地方都變成黑色
result = cv2.bitwise_and(frame,frame, mask= mask)
3.3車道檢測
利用canny邊緣檢測算子結合Hough線變換進行車道檢測,

#車道檢測
def canny(frame):
gray=cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY)
blur=cv2.GaussianBlur(gray,(5,5),0)
canny=cv2.Canny(blur,50,150)
return canny
def region_of_interest(frame):
height=frame.shape[0]
polygons=np.array([
[(0,height),(500,0),(800,0),(1300,550),(1100,height)]
])
mask=np.zeros_like(frame)
cv2.fillPoly(mask,polygons,255)
masked_image=cv2.bitwise_and(frame,mask)
return masked_image
def display_lines(frame,lines):
line_image=np.zeros_like(frame)
if lines is not None:
for line in lines:
x1,y1,x2,y2=line.reshape(4)
cv2.line(line_image, (x1, y1), (x2, y2), (0, 255, 0), 3)
return line_image
lane_image=np.copy(frame)
canny=canny(lane_image)
cropped_image=region_of_interest(canny)
lines=cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=5,maxLineGap=300)
line_image=display_lines(lane_image,lines)
frame=cv2.addWeighted(lane_image,0.8,line_image,1,1)
cv2.imshow('video', frame)
4.等高線
canny邊緣檢測器等演算法用于查找邊緣像素影像中的邊緣分界,但它并沒有告訴我們如何找到物件或物體不能結合的點和邊,這里我們可以使用OpenCV實作的cv2.findContours()作為輪廓的概念,
定義-“輪廓表示影像中曲線的點的串列,”
輪廓由序串列示,每個序列都對下一個點的位置資訊進行編碼,我們在roi中多次運行cv2.findConteurs()來獲取物體,然后使用cv2.drawContours()繪制輪廓區域,輪廓可以是點、邊、多邊形等,所以在繪制等高線時,我們做多邊形近似,求出邊的長度和區域的面積,
函式cv2.drawContours()的作業原理是從根節點開始繪制一棵樹(資料結構),然后連接后續點、邊界框和Freeman鏈碼,
thresh = mask
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# 定義輪廓的最小面積(忽略min以下的所有值)
min_area = 1000
cont_filtered = []
# 過濾掉最小面積以下的所有輪廓線
for cont in contours:
if cv2.contourArea(cont) > min_area:
cont_filtered.append(cont)
cnt = cont_filtered[0]
# 圍繞輪廓畫出矩形
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(frame,[box],0,(0,0,255),2)
rows,cols = thresh.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(frame,(cols-1,righty),(0,lefty),(0,255,0),2)
找到輪廓后的另一個重要任務是匹配它們,匹配輪廓意味著我們有兩個獨立的計算輪廓來相互比較,或者有一個輪廓與一個抽象模板進行比較,
5.特征矩
我們可以通過計算輪廓矩來比較兩個輪廓,“特征矩是輪廓的總特征,通過將輪廓的所有像素相加來計算,”

力矩型別
空間特征矩:m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
中心特征矩:mu20, mu11, mu02, mu30, mu21, mu12, mu03.
Hu特征矩:有七個Hu特征矩(h0-h6)或(h1-h7),這兩個符號都使用,
我們使用cv2.fitEllipse()計算特征矩并在點上擬合橢圓,從輪廓線和特征矩中找到角度,因為改變車道需要45度旋轉,這被視為汽車轉彎角度的閾值,

M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
print('x= ', cx, ' y= ', cy, ' angle = ', round(rect[2],2))
if(round(rect[2],2))<-45:
# print('Lane change detected')
popupmsg('Lane change detected')
現在,我們可以使用Tkinter來創建一個簡單的彈出視窗來警告變化,而不僅僅是列印變化的檢測結果,
if(round(rect[2],2))<-45:
popupmsg('Lane change detected')
def popupmsg(msg):
popup = tk.Tk()
popup.wm_title("Message")
label = ttk.Label(popup, text=msg, font=NORM_FONT)
label.pack(side="top", fill="x", pady=10)
B1 = ttk.Button(popup, text="Okay", command = popup.destroy)
B1.pack()
popup.mainloop()

在車架上畫矩形,用綠線測量角度


6.總結和未來
在本教程中,將使用車道變化檢測方法探索智能汽車導航的一個小演示,
計算機視覺正在迅速發展,它的應用不僅在汽車的區域導航,而且在火星上的導航和產品檢測領域也在進步,甚至在醫學應用中也在開發和用于早期在X射線影像中檢測癌癥和腫瘤,
單擊此處獲取GitHub帳戶的源代碼:https://github.com/Hitesh-Valecha/Car_Opencv
參考文獻
- Bradski, Gary and Kaehler, Adrian, Learning OpenCV: Computer Vision in C++ with the OpenCV Library, O’Reilly Media, Inc., 2nd edition, 2013, @10.5555/2523356, ISBN — 1449314651.
- Laganiere, Robert, OpenCV Computer Vision Application Programming Cookbook, Packt Publishing, 2nd edition, 2014, @10.5555/2692691, ISBN — 1782161481.
原文鏈接:https://towardsdatascience.com/lane-change-detection-computer-vision-at-next-stage-914973f96f4b
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/197486.html
標籤:其他
上一篇:使用微創聯合M5S空氣檢測儀、樹莓派3b+、prometheus、grafana實作空氣質量持續監控告警WEB可視化
下一篇:通過深層神經網路生成音樂
