这几天参加软件杯的竞赛(不知道能不能过预选赛。。)我负责的是信号灯的识别。我制作了一个简易的信号灯识别文件。为什么说是简易的,因为它实际上不算是真正的信号灯识别。我的思路是在图片中根据颜色函数找相应的颜色,然后在上面画一个圆圈,如果这个圆圈里颜色覆盖打到相应程度,则会认为它是信号灯。本来是简单的颜色识别,但是实际实验发现,因为信号灯的颜色比普通的红黄绿要不一样。所以效果还很不错,误识别的几率也不高。

以下为代码及效果图:

#!/usr/bin/env python
# coding: utf-8
# created by hevlhayt@foxmail.com
# Date: 2016/1/15
# Time: 19:20
#
import os
import cv2
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, 43, 46])
    upper_red1 = np.array([10, 255, 255])
    lower_red2 = np.array([156, 45, 45])
    upper_red2 = np.array([180, 255, 255])
    lower_green = np.array([40, 50, 90])
    upper_green = np.array([80, 255, 255])
    # lower_yellow = np.array([15,100,100])
    # upper_yellow = np.array([35,255,255])
   
lower_yellow = np.array([20, 150, 155])
    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.3 / 10
    if r_circles is not None:
        r_circles = np.uint16(np.around(r_circles))
        print('R')
        for i in r_circles[0, :]:
            if i[0] > size[1] or i[1] > size[0]or i[1] > size[0]*bound:
                print('Ri')
                continue
           
print('Rii')
            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
            print('Riii')
            if h / s > 150:
                print('Riiii')
                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))
        print('G')
        for i in g_circles[0, :]:
            if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound:
                print('Gi')
                continue
           
print('Gii')
            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
            print('Giii')
            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))
        print('Y')
        for i in y_circles[0, :]:
            if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound:
                print('Yi')
                continue
           
print('Yii')
            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
            print('Yiii')
            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'):
    #        detect(path, f)

   
detect(path,'17.jpg')