我对图像处理和opencv相当陌生。我需要检测一些球的颜色。我首先使用cv2.HoughCircles
检测这些球,但此后我被卡住了。
大多数在线答案都建议使用轮廓并将其与颜色范围匹配或计算到最接近颜色的距离。但是我找不到将cv2.HoughCircles
的输出转换为轮廓的方法(我不确定是否可行)
while reader.isOpened():
ret, frame = reader.getCapture()
if ret:
workingFrame = imutils.resize(frame, width=600)
copy = frame.copy()
grayMask = cv2.cvtColor(copy, cv2.COLOR_BGR2GRAY)
circlesArr = cv2.HoughCircles(grayMask, cv2.HOUGH_GRADIENT, 1.3, 20, param1=40, param2=30, minRadius=5, maxRadius=20)
if circlesArr is not None:
for circle in circlesArr[0, :]:
# detect colors
cv2.circle(frame, (circle[0], circle[1]), circle[2], GREEN, 1)
cv2.circle(frame, (circle[0], circle[1]), 2, GREEN, 2)
cv2.imshow("frame", frame)
else:
break
if quitKeyPressed():
break
答案 0 :(得分:1)
我设法通过以下步骤找到每个圆圈的主色:
首先,我用cv2.HoughCircles
检测到了圆圈:
def detectCirclesWithDp(frame, dp=1):
blurred = cv2.medianBlur(frame, 25)
grayMask = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
# cannyMask = cv2.Canny(grayMask, 50, 240)
return cv2.HoughCircles(grayMask, cv2.HOUGH_GRADIENT, dp, 40, param1=10, param2=30, minRadius=20, maxRadius=70)
然后为每个圆圈选择一个投资回报率:
def getROI(frame, x, y, r):
return frame[int(y-r/2):int(y+r/2), int(x-r/2):int(x+r/2)]
然后,我使用kmeans和颜色蒙版计算该区域中最主要的颜色:
COLOR_NAMES = [RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE, RED_2]
COLOR_RANGES_HSV = {
"red": [(0, 50, 10), (10, 255, 255)],
"orange": [(10, 50, 10), (25, 255, 255)],
"yellow": [(25, 50, 10), (35, 255, 255)],
"green": [(35, 50, 10), (80, 255, 255)],
"cyan": [(80, 50, 10), (100, 255, 255)],
"blue": [(100, 50, 10), (130, 255, 255)],
"purple": [(130, 50, 10), (170, 255, 255)],
"red ": [(170, 50, 10), (180, 255, 255)]
}
def getMask(frame, color):
blurredFrame = cv2.GaussianBlur(frame, (3, 3), 0)
hsvFrame = cv2.cvtColor(blurredFrame, cv2.COLOR_BGR2HSV)
colorRange = COLOR_RANGES_HSV[color]
lower = np.array(colorRange[0])
upper = np.array(colorRange[1])
colorMask = cv2.inRange(hsvFrame, lower, upper)
colorMask = cv2.bitwise_and(blurredFrame, blurredFrame, mask=colorMask)
return colorMask
def getDominantColor(roi):
roi = np.float32(roi)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret, label, center = cv2.kmeans(roi, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape(roi.shape)
pixelsPerColor = []
for color in COLOR_NAMES:
mask = getMask(res2, color)
greyMask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
count = cv2.countNonZero(greyMask)
pixelsPerColor.append(count)
return COLOR_NAMES[pixelsPerColor.index(max(pixelsPerColor))]
一切融合在一起:
def detect():
circles = detector.detectCirclesWithDp(imgCopy)
if circles is not None:
for circle in circles[0, :]:
if imageUtils.inFrame(img, circle[0], circle[1]):
roi = imageUtils.getROI(imgCopy, circle[0], circle[1], circle[2])
color = colorlabeler.getDominantColor(roi)
cv2.circle(img, (circle[0], circle[1]), circle[2], colorlabeler.COLORS_RGB["green"], 1)
cv2.circle(img, (circle[0], circle[1]), 2, colorlabeler.COLORS_RGB["green"], 2)
cv2.putText(img, color, (int(circle[0] + 40), int(circle[1] + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
colorlabeler.COLORS_RGB["green"])
while True:
cv2.imshow("frame", img)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
最后是结果: