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