行空板红绿灯检测系统
该项目旨在利用行空板的高级驾驶员辅助系统 (ADAS) 技术开发交通灯检测系统。该系统的目的是通过精确识别十字路口和人行横道处的交通灯来加强道路安全并简化交通管理。通过计算机视觉和机器学习的应用,我们的项目致力于向驾驶员和交通当局提供实时信息。这项工作旨在提高交通流量并减少因信号违规而发生事故的可能性。
我们使用行空板-ADAS项目的交通灯检测的主要功能是交通灯检测和信号识别。该系统将使用摄像头和传感器持续监控前方道路。它将准确检测交通灯的存在和位置,包括红色、绿色还是黄色。检测到交通灯后,系统将识别当前信号状态(红色、绿色或黄色)。这些信息对于驾驶员和系统的决策过程都至关重要。此外,还包括速度测量和音乐控制等ADAS功能。
硬件清单
简介
感谢DFROBOT赞助行空板套件。该硬件的可能性是无限的。
配置 Wi-Fi 并运行以下程序:
from unihiker import GUI
import time
gui = GUI()
gui.draw_text(text="Hello, Community!", origin = "center", x=120, y=160, color='#800080')
while True:
time.sleep(1)
人脸检测测试
接下来,我们使用haar级联进行了简单的人脸检测测试。我们使用jupyter notebook在行空板上运行程序。
步骤1 在VSCode上编程
在VSCode中,有一个Remote插件,允许您通过SSH连接到远程主机,从而使您可以直接对行空板进行编程。
要使用此功能,首先,从 VSCode 扩展市场安装“Python”扩展。然后,搜索“remote”扩展并安装“Remote - SSH”。安装完成后,您将在VSCode中找到Remote Explorer。要添加新连接,请输入 SSH 帐户“root”和密码“dfrobot”。
通过 USB 连接时,IP 地址固定为“10.1.2.3”,因此输入“root@10.1.2.3”并选择“Linux”。出现提示时输入密码。
注意:如果连接失败,请多次重试。
连接后,您可以选择行空板目录来打开文件并编写程序来执行。
第2步 编程交通灯控制器
我们已经使用 Arduino 制作了一个交通灯。您可以在这里找到该项目。
https://www.youtube.com/watch?v=1vDx2Lhzp9k
步骤3 设置硬件
将USB-C电缆插入行空板的电源端口。拿起USB相机电缆并将其牢固地插入 行空板的USB端口。确保相机镜头能够清晰地看到您要检测的LED。您可以调整相机的角度或定位行空板本身来实现此目的。
步骤4 编程交通灯检测
现在,我们将使用Jupyter Notebook 来对交通灯检测进行编程。我们将使用颜色阈值来检测交通灯的颜色。
您将导入 OpenCV(用于图像处理)和 NumPy(用于数值运算)等库。使用 OpenCV 读取包含交通灯的图像。指定所选颜色空间(RGB 或 BGR)中红色、黄色和绿色的最小值和最大值。使用阈值处理为每种颜色生成单独的二值图像(掩模)。将原始图像与处理后的二进制掩模或最终检测结果一起显示。
阈值的局限性
颜色阈值可能对光照变化和背景颜色敏感。它可能会遇到阴影或重叠物体的问题。
import os
import cv2
from unihiker import GUI
import numpy as np
def detect(filepath, file):
font = cv2.FONT_HERSHEY_SIMPLEX
img = cv2.imread(filepath+file)
cimg = img
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# color range
lower_red1 = np.array([0,100,100])
upper_red1 = np.array([10,255,255])
lower_red2 = np.array([160,100,100])
upper_red2 = np.array([180,255,255])
lower_green = np.array([40,50,50])
upper_green = np.array([90,255,255])
# lower_yellow = np.array([15,100,100])
# upper_yellow = np.array([35,255,255])
lower_yellow = np.array([15,150,150])
upper_yellow = np.array([35,255,255])
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
maskg = cv2.inRange(hsv, lower_green, upper_green)
masky = cv2.inRange(hsv, lower_yellow, upper_yellow)
maskr = cv2.add(mask1, mask2)
size = img.shape
# print size
# hough circle detect
r_circles = cv2.HoughCircles(maskr, cv2.HOUGH_GRADIENT, 1, 80,
param1=50, param2=10, minRadius=0, maxRadius=30)
g_circles = cv2.HoughCircles(maskg, cv2.HOUGH_GRADIENT, 1, 60,
param1=50, param2=10, minRadius=0, maxRadius=30)
y_circles = cv2.HoughCircles(masky, cv2.HOUGH_GRADIENT, 1, 30,
param1=50, param2=5, minRadius=0, maxRadius=30)
# traffic light detect
r = 5
bound = 4.0 / 10
if r_circles is not None:
r_circles = np.uint16(np.around(r_circles))
for i in r_circles[0, :]:
if i[0] > size[1] or i[1] > size[0]or i[1] > size[0]*bound:
continue
h, s = 0.0, 0.0
for m in range(-r, r):
for n in range(-r, r):
if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]:
continue
h += maskr[i[1]+m, i[0]+n]
s += 1
if h / s > 50:
cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2)
cv2.circle(maskr, (i[0], i[1]), i[2]+30, (255, 255, 255), 2)
cv2.putText(cimg,'RED',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA)
if g_circles is not None:
g_circles = np.uint16(np.around(g_circles))
for i in g_circles[0, :]:
if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound:
continue
h, s = 0.0, 0.0
for m in range(-r, r):
for n in range(-r, r):
if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]:
continue
h += maskg[i[1]+m, i[0]+n]
s += 1
if h / s > 100:
cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2)
cv2.circle(maskg, (i[0], i[1]), i[2]+30, (255, 255, 255), 2)
cv2.putText(cimg,'GREEN',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA)
if y_circles is not None:
y_circles = np.uint16(np.around(y_circles))
for i in y_circles[0, :]:
if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound:
continue
h, s = 0.0, 0.0
for m in range(-r, r):
for n in range(-r, r):
if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]:
continue
h += masky[i[1]+m, i[0]+n]
s += 1
if h / s > 50:
cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2)
cv2.circle(masky, (i[0], i[1]), i[2]+30, (255, 255, 255), 2)
cv2.putText(cimg,'YELLOW',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA)
cv2.imshow('detected results', cimg)
cv2.imwrite(path+'//result//'+file, cimg)
# cv2.imshow('maskr', maskr)
# cv2.imshow('maskg', maskg)
# cv2.imshow('masky', masky)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
path = os.path.abspath('..')+'//light//'
for f in os.listdir(path):
print (f)
if f.endswith('.jpg') or f.endswith('.JPG') or f.endswith('.png') or f.endswith('.PNG'):
detect(path, f)
步骤5 大功告成!
https://youtu.be/Z9scQUasncI
Unihiker 检测交通灯 LED 并在其上标记边界框/圆圈。我们终于成功地完成了这个项目。
关注我:
下次 Electroverse.ai 见!
谢谢阅读!
原作者:Electroverse