无需ML的实时目标检测绘制BBox
问题描述
我正在尝试在没有任何ML的情况下进行实时目标检测。该方法是根据对象的颜色配置文件来识别对象。我试着用一种颜色识别一个矩形物体,并画一个边框。代码如下:
import cv2
import numpy as np
class ColourBounds:
def __init__(self, rgb):
hsv = cv2.cvtColor(np.uint8([[[rgb[2], rgb[1], rgb[0]]]]), cv2.COLOR_BGR2HSV).flatten()
lower = [hsv[0] - 10]
upper = [hsv[0] + 10]
if lower[0] < 0:
lower.append(179 + lower[0]) # + negative = - abs
upper.append(179)
lower[0] = 0
elif upper[0] > 179:
lower.append(0)
upper.append(upper[0] - 179)
upper[0] = 179
self.lower = [np.array([h, 100, 100]) for h in lower]
self.upper = [np.array([h, 255, 255]) for h in upper]
def contains_vertical(r1, r2):
x1, y1, w1, h1 = r1
x2, y2, w2, h2 = r2
return x1 <= x2 < x1 + w1 and x1 <= x2 + w2 < x1 + w1
def drawLabel(w, h, x, y, text, frame):
cv2.rectangle(frame,(x,y),(x+w,y+h),(120,0,0),2)
cv2.putText(frame, text, (x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,255), 2)
colourMap = {"Antigen Device": ColourBounds((237,237,237))}
while(True):
frame = cv2.imread('antigen.png')
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
rects = {}
for name, colour in colourMap.items():
mask = cv2.inRange(hsv, colour.lower[0], colour.upper[0])
if len(colour.lower) == 2:
mask = mask | cv2.inRange(hsv, colour.lower[1], colour.upper[1])
conts, heirarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if (len(conts) == 0):
continue
biggest = sorted(conts, key=cv2.contourArea, reverse=True)[0]
rect = cv2.boundingRect(biggest)
x, y, w, h = rect
if w < 50 or h < 50:
continue
if name == "Antigen Device":
if any([contains_vertical(rects[n], rect) for n in rects]):
continue
rects[name] = rect
drawLabel(w, h, x, y, name, frame)
cv2.imshow('image',frame)
k = cv2.waitKey(0) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
cv2.waitKey(1)
但是,我没有看到边框或标签。下面是我的照片。不应用任何更改:
解决方案
您正在尝试进行颜色检测,然后在其周围绘制一个边框。
最简单的方法:
第一步:实现颜色检测。
我实现了以下代码来为您的图像查找正确的遮罩值。使用轨迹栏,当您对结果感到满意时,按Q键,系统将为您打印掩码的值。
注意:除了你的目标之外,你可以找到更多的小轮廓。
我发现这些值非常有效:
h_min,h_max,s_min,s_max,v_min,v_max:0 179 0 15 223 255
import cv2
import numpy as np
def empty():
pass
while True:
img = cv2.imread(Path to your image)
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("Hue Min", "TrackBars")
h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
mask = cv2.inRange(imgHSV, lower, upper)
imgResult = cv2.bitwise_and(img, img, mask=mask)
# for OpenCV 4
contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
cv2.CHAIN_APPROX_NONE)
# ---For OpenCV 3---
# _, contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
# cv2.CHAIN_APPROX_NONE)
# ---For OpenCV 3---
for contour in contours:
cv2.drawContours(img, contour, -1, (0, 255, 0), 3)
cv2.imshow("Original", img)
cv2.imshow("Result", imgResult)
if cv2.waitKey(27) & 0xFF == ord('q'):
print(h_min, h_max, s_min, s_max, v_min, v_max)
break
第二步:只在目标周围画边界框。(2个绘制选项)
代码与前面类似,但现在我们知道了正确的值,我们将在所需的等高线周围绘制一条线。我们的目标是获得最大的轮廓,因此我们可以使用contourArea()方法提取轮廓的大小,然后仅在轮廓足够大的情况下绘制边界框。它的实现与您的代码略有不同,但您可以根据您的逻辑对其进行调整(对等高线区域的大小进行排序,并仅在最大的区域上绘制)。
例如:
import cv2
import numpy as np
while True:
frame = cv2.imread("stackoverflow2pic.jpeg")
blurred_frame = cv2.GaussianBlur(frame, (5, 5), 0)
hsv = cv2.cvtColor(blurred_frame, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 223])
upper = np.array([179, 15, 255])
mask = cv2.inRange(hsv, lower, upper)
# for OpenCV 4
contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
cv2.CHAIN_APPROX_NONE)
# ---For OpenCV 3---
# _, contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
# cv2.CHAIN_APPROX_NONE)
# ---For OpenCV 3---
for contour in contours:
area = cv2.contourArea(contour)
if area > 5000:
# -- Draw Option 1 --
cv2.drawContours(frame, contour, -1, (0, 255, 0), 3)
# -- Draw Option 2--
# rect = cv2.boundingRect(contour)
# x, y, w, h = rect
# cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Mask", mask)
cv2.imshow("Frame", frame)
cv2.waitKey(1)
结果(绘图选项1):
结果(绘图选项2):
相关文章