The project aims to develop a Traffic Light Detection system utilizing Unihiker's Advanced Driver Assistance System (ADAS) technology. This system's purpose is to bolster road safety and streamline traffic management by precisely identifying traffic lights at intersections and pedestrian crossings. Through the application of computer vision and machine learning, our project strives to deliver real-time information to both drivers and traffic authorities. This effort is geared toward enhancing traffic flow and diminishing the likelihood of accidents stemming from signal violations.
The main functions of our Traffic Light Detection using the Unihiker - ADAS project are Traffic Light Detection and Signal Recognition. The system will continuously monitor the road ahead using cameras and sensors. It will accurately detect the presence and location of traffic lights, including red, green, and yellow signals. After detecting the traffic light, the system will recognize the current signal state (red, green, or yellow). This information is crucial for both drivers and the system's decision-making process. ADAS features such as speed measurement, and music control are also included.
Quick Introduction
Thanks to DFROBOT for sponsoring this unihiker kit. The possibilities of this hardware are limitless.
After configuring Wi-Fi and running the following script:
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)
Face Detection Test
Next, we made a simple face detection test using a haar cascade. We used jupyter notebook to run the program on the unihiker.
In VSCode, there is a Remote plug-in that allows you to connect to a remote host via SSH, enabling you to directly program the UNIHIKER.
To use this feature, first, install the "Python" extension from the VSCode Extensions marketplace. Then, search for the "remote" extension and install "Remote - SSH".Once the installation is complete, you will find the Remote Explorer in VSCode. To add a new connection, enter the SSH account as "root" and the password as "dfrobot".
When connected via USB, the IP address is fixed as "10.1.2.3", so enter "[email protected]" and select "Linux". Enter the password when prompted.
Note: If the connection fails, please retry multiple times.
Once connected, you can select the UNIHIKER directory to open files and write programs for execution.
Plug the USB-C cable into the unihiker's power port. Take your USB camera cable and plug it securely into the unihiker's USB port. Make sure the camera lens has a clear view of the LEDs you want to detect. You can adjust the camera's angle or position the unihiker itself to achieve this.
Now, we will be using jupyter notebook to program the traffic light detection. We''ll be using the color thresholding to detect the color of the traffic light.
You'll import libraries like OpenCV (for image processing) and NumPy (for numerical operations). Use OpenCV to read the image containing the traffic light. Specify the minimum and maximum values for red, yellow, and green in the chosen color space (RGB or BGR). Generate separate binary images (masks) for each color using thresholding. Display the original image alongside the processed binary masks or final detection results.
Limitations of Thresholding
Color thresholding can be sensitive to lighting variations and background colors. It might struggle with shadows or overlapping objects.
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)
The Unihiker detects the traffic light LEDs and marks a bounding box/circle on it. We finally did this project successfully.
Follow me:
YouTube: https://youtube.com/@electroverse_ai
Facebook: https://facebook.com/electroverseai
Instagram: https://www.instagram.com/electroverse.ai/
See you next time on Electroverse.ai!
Thanks for reading!