这是在 Python/OpenCV 中使用 G 与 R 2D 直方图进行判断的一种方法。因此,如果二维直方图右上角有很多白色,则为红色,如果沿左下角,则为绿色,如果仅沿对角线,则为黄色。
因此,为区域制作掩码,对结果进行掩码并使用 np.count_nonzero() 计算非零像素的数量。
输入 1(红色)
输入 2(绿色)
输入 3(黄色)
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('')
红色面具:
绿色面具:
红色直方图:
绿色直方图:
黄色直方图:
结果:
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