Here is one way to tell in Python/OpenCV using the G vs R 2D histogram. So if the 2D histogram has lots of white in the upper right, it is red, if along the lower left, it is green and if only along the diagonal, it is yellow.
So, make masks for the regions, mask the results and count the number of non-zero pixels using np.count_nonzero().
Input 1 (red)
Input 2 (green)
Input 3 (yellow)
import cv2
import numpy as np
import skimage.exposure as exposure
import os
filenames = ['traffic_light_red.jpg', 'traffic_light_green.jpg', 'traffic_light_yellow.jpg']
for filename in filenames:
print(filename)
# get name without suffix
name = os.path.splitext(filename)[0]
# read image
img = cv2.imread(filename)
# calculate 2D histograms for pairs of channels: GR
histGR = cv2.calcHist([img], [1, 2], None, [256, 256], [0, 256, 0, 256])
# histogram is float and counts need to be scale to range 0 to 255
histScaled = exposure.rescale_intensity(histGR, in_range=(0,1), out_range=(0,255)).clip(0,255).astype(np.uint8)
# make masks
ww = 256
hh = 256
ww13 = ww // 3
ww23 = 2 * ww13
hh13 = hh // 3
hh23 = 2 * hh13
black = np.zeros_like(histScaled, dtype=np.uint8)
# specify points in OpenCV x,y format
ptsUR = np.array( [[[ww13,0],[ww-1,hh23],[ww-1,0]]], dtype=np.int32 )
redMask = black.copy()
cv2.fillPoly(redMask, ptsUR, (255,255,255))
ptsBL = np.array( [[[0,hh13],[ww23,hh-1],[0,hh-1]]], dtype=np.int32 )
greenMask = black.copy()
cv2.fillPoly(greenMask, ptsBL, (255,255,255))
#Test histogram against masks
region = cv2.bitwise_and(histScaled,histScaled,mask=redMask)
redCount = np.count_nonzero(region)
region = cv2.bitwise_and(histScaled,histScaled,mask=greenMask)
greenCount = np.count_nonzero(region)
print('redCount:',redCount)
print('greenCount:',greenCount)
# Find color
threshCount = 100
if redCount > greenCount and redCount > threshCount:
color = "red"
elif greenCount > redCount and greenCount > threshCount:
color = "green"
elif redCount < threshCount and greenCount < threshCount:
color = "yellow"
else:
color = "other"
print("color: ",color)
# save result
cv2.imwrite(name + '_histogram.jpg', histScaled)
cv2.imwrite('redMask.jpg', redMask)
cv2.imwrite('greenMask.jpg', greenMask)
# view results
cv2.imshow("hist", histScaled)
cv2.imshow("redMask", redMask)
cv2.imshow("greenMask", greenMask)
cv2.waitKey(0)
cv2.destroyAllWindows()
print('')
Red Mask:
Green Mask:
Red Histogram:
Green Histogram:
Yellow Histogram:
Results:
traffic_light_red.jpg
redCount: 2627
greenCount: 0
color: red
traffic_light_green.jpg
redCount: 0
greenCount: 1138
color: green
traffic_light_yellow.jpg
redCount: 0
greenCount: 0
color: yellow
CLICK HERE to find out more related problems solutions.