UNIHIKER - Traffic Light Detection system

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.

HARDWARE LIST
1 UNIHIKER
1 USB Camera
1 Arduino Uno
1 RED LED Light Module
1 Green LED Light Module
1 White LED Light Module

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. 

 

 

 

STEP 1
Programming on VSCode

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 "root@10.1.2.3" 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.

 

 

STEP 2
Programming Traffic Light Controller

We have already made a traffic light using Arduino. You can find the project here.  

 

 

STEP 3
Setting up the Hardware

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.


 


 


 


 

STEP 4
Programming Traffic Light Detection

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.

CODE
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)

STEP 5
Playtime!

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! 

License
All Rights
Reserved
licensBg
2