检查一个对象的边界框是否在另一个对象的边界框内
Check to see if a bounding box of an object is inside the bounding box of another object
我有一段视频,人们在不同的房子里走来走去。我在不同的房屋周围创建了一个固定的边界框,并实施了一个跟踪器来跟踪人们的移动。我现在想检查任何人的边界框是否在任何房屋的边界框内。
因为这是一个视频,检查 True 或 False - 即一个人是否在边界框内会不断随着人们四处走动而改变。例如,我包含了视频 起始帧的图片 。如您所见,Person 0 根本不在任何房屋的边界框内。但是,无论如何它都会打印 True。另外,我还想说的是,我检查了该平台上的多个其他来源和帖子以寻求一些指导,但我找不到任何可以帮助我解决问题的东西。
我得到的输出:
Person 0 : True
Person 1 : True
Person 2 : True
Person 0 : True
Person 1 : True
...
预期输出如下(预期输出的前 3 行对应于下图):
Person 0: False
Person 1: True
Person 2: True
Person 0: False
Person 1: True
...
这是我到目前为止所做的:
# boxes_houses = [(#, #, #, #), (#, #, #, #), ...]
while cap.isOpened():
success, frame = cap.read()
if not success:
break
# get updated location of objects in subsequent frames
success, boxes_person = multiTracker.update(frame)
# boxes_persons = [(#, #, #, #), (#, #, #, #), ...]
cnt_person = 0
cnt_house = 0
for box_person, box_house in zip(boxes_persons, boxes_houses):
x_p1 = int(box_person[0])
y_p1 = int(box_person[1])
x_p2 = int(box_person[2])
y_p2 = int(box_person[3])
person_coords = {'x1': x_p1, 'y1': y_p1, 'x2': x_p2, 'y2': y_p2}
cv2.rectangle(frame, (x_p1, y_p1), (x_p1 + x_p2, y_p1 + y_p2), (0, 0, 0), 2, 1)
cv2.putText(frame, "House: {}".format(cnt_house), (x1, y1 - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0), 1)
x_h1 = int(box_house[0])
y_h1 = int(box_house[1])
x_h2 = int(box_house[2])
y_h2 = int(box_house[3])
cv2.rectangle(frame, (x_h1 , y_h1), (x_h1 + x_h2, y_h1+ y_h2), (0, 0, 255), 2, 1)
cv2.putText(frame, "Person: {}".format(cnt_person ), (int(box_house[0]), int(box_house[1] - 5)), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)
## CHECK TO SEE IF BBOX OF PERSONS ARE INSIDE BBOX OF HOMES ##
house1 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
house2 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
house3 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
if (person_coords['x1'] < house1['x1'] and person_coords['y1'] < house1['y1'] or person_coords['x2'] < house1['x2'] and person_coords['y2'] < house1['y2']) or (person_coords['x1'] < house2['x1'] and person_coords['y1'] < house2['y1'] or person_coords['x2'] < house2['x2'] and person_coords['y2'] < house2['y2']) or (person_coords['x1'] < house3['x1'] and person_coords['y1'] < house3['y1'] or person_coords['x2'] < house3['x2'] and person_coords['y2'] < house3['y2']):
print ("Person", num_person, ": True\n")
else:
print ("Person", num_person, ": False\n")
cnt_house+= 1
cnt_person+= 1
# show frame
cv2.imshow('MultiTracker', frame)
# quit on ESC button
if cv2.waitKey(1) & 0xFF == 27: # Esc pressed
break
如有任何帮助,我们将不胜感激!
我认为问题来自位置检查(这很难阅读,因为它都在 if 语句中的一行上)。
让我们首先定义一个函数来检查一个人是否在给定的房子里:
def isInside(person, house):
"""
person is the dict with x1, y1, x2 and y2 for that person
house is the dict with x1, y1, x2 and y2 for that person
"""
# First we make sure we compare things in the right order
# You can skip that part if you are sure that in all cases x1 < x2 and y1 < y2
p_xmin = min(person["x1"], person["x2"])
p_xmax = max(person["x1"], person["x2"])
p_ymin = min(person["y1"], person["y2"])
p_ymax = max(person["y1"], person["y2"])
h_xmin = min(house["x1"], house["x2"])
h_xmax = max(house["x1"], house["x2"])
h_ymin = min(house["y1"], house["y2"])
h_ymax = max(house["y1"], house["y2"])
# Then you perform your checks. From what I understood,
# you want the result to be true if any corner of the person
# is inside the house's bounding box.
p_corners = [
(p_xmin, p_ymin),
(p_xmin, p_ymax),
(p_xmax, p_ymin),
(p_xmax, p_ymax)]
for corner in p_corners:
in_range_along_x = corner[0] < h_xmax and corner[0] > h_xmin
in_range_alond_y = corner[1] < h_ymax and corner[1] > h_ymin
if in_range_along_x and in_range_along_y:
return True
# If we get there, then the person is not inside that house
return False
您还可以修改上面的函数以使用人的边界框的中心而不是角,或者检查所有角是否都在里面。这是作为奖励的中心版本:
def centerIsInside(person, house):
"""
person is the dict with x1, y1, x2 and y2 for that person
house is the dict with x1, y1, x2 and y2 for that person
"""
# First we make sure we compare things in the right order
# You can skip that part if you are sure that in all cases x1 < x2 and y1 < y2
h_xmin = min(house["x1"], house["x2"])
h_xmax = max(house["x1"], house["x2"])
h_ymin = min(house["y1"], house["y2"])
h_ymax = max(house["y1"], house["y2"])
# We compute the center of the person:
p_xcenter = (person["x1"]+person["x2"])/2
p_ycenter = (person["y1"]+person["y2"])/2
# Then you perform your checks.
in_range_along_x = p_xcenter < h_xmax and corner[0] > p_xcenter
in_range_alond_y = p_ycenter < h_ymax and corner[1] > p_ycenter
if in_range_along_x and in_range_along_y:
return True
else:
return False
然后您可以使用该函数来执行检查,而不是那个长 if 语句:
# [...]
houses = [house1, house2, house3]
isinside_checks = []
for house in houses:
isinside_checks.append(isInside(person_coords, house))
if any(inside_checks):
print ("Person", num_person, ": True\n")
else:
print ("Person", num_person, ": False\n")
# [...]
您还可以修改 isInside
函数,使其根据参数执行不同类型的检查(任何角、中心、所有角...)
我有一段视频,人们在不同的房子里走来走去。我在不同的房屋周围创建了一个固定的边界框,并实施了一个跟踪器来跟踪人们的移动。我现在想检查任何人的边界框是否在任何房屋的边界框内。
因为这是一个视频,检查 True 或 False - 即一个人是否在边界框内会不断随着人们四处走动而改变。例如,我包含了视频 起始帧的图片 。如您所见,Person 0 根本不在任何房屋的边界框内。但是,无论如何它都会打印 True。另外,我还想说的是,我检查了该平台上的多个其他来源和帖子以寻求一些指导,但我找不到任何可以帮助我解决问题的东西。
我得到的输出:
Person 0 : True
Person 1 : True
Person 2 : True
Person 0 : True
Person 1 : True
...
预期输出如下(预期输出的前 3 行对应于下图):
Person 0: False
Person 1: True
Person 2: True
Person 0: False
Person 1: True
...
这是我到目前为止所做的:
# boxes_houses = [(#, #, #, #), (#, #, #, #), ...]
while cap.isOpened():
success, frame = cap.read()
if not success:
break
# get updated location of objects in subsequent frames
success, boxes_person = multiTracker.update(frame)
# boxes_persons = [(#, #, #, #), (#, #, #, #), ...]
cnt_person = 0
cnt_house = 0
for box_person, box_house in zip(boxes_persons, boxes_houses):
x_p1 = int(box_person[0])
y_p1 = int(box_person[1])
x_p2 = int(box_person[2])
y_p2 = int(box_person[3])
person_coords = {'x1': x_p1, 'y1': y_p1, 'x2': x_p2, 'y2': y_p2}
cv2.rectangle(frame, (x_p1, y_p1), (x_p1 + x_p2, y_p1 + y_p2), (0, 0, 0), 2, 1)
cv2.putText(frame, "House: {}".format(cnt_house), (x1, y1 - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0), 1)
x_h1 = int(box_house[0])
y_h1 = int(box_house[1])
x_h2 = int(box_house[2])
y_h2 = int(box_house[3])
cv2.rectangle(frame, (x_h1 , y_h1), (x_h1 + x_h2, y_h1+ y_h2), (0, 0, 255), 2, 1)
cv2.putText(frame, "Person: {}".format(cnt_person ), (int(box_house[0]), int(box_house[1] - 5)), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)
## CHECK TO SEE IF BBOX OF PERSONS ARE INSIDE BBOX OF HOMES ##
house1 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
house2 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
house3 = {'x1': #, 'y1': #, 'x2': #, 'y2': #}
if (person_coords['x1'] < house1['x1'] and person_coords['y1'] < house1['y1'] or person_coords['x2'] < house1['x2'] and person_coords['y2'] < house1['y2']) or (person_coords['x1'] < house2['x1'] and person_coords['y1'] < house2['y1'] or person_coords['x2'] < house2['x2'] and person_coords['y2'] < house2['y2']) or (person_coords['x1'] < house3['x1'] and person_coords['y1'] < house3['y1'] or person_coords['x2'] < house3['x2'] and person_coords['y2'] < house3['y2']):
print ("Person", num_person, ": True\n")
else:
print ("Person", num_person, ": False\n")
cnt_house+= 1
cnt_person+= 1
# show frame
cv2.imshow('MultiTracker', frame)
# quit on ESC button
if cv2.waitKey(1) & 0xFF == 27: # Esc pressed
break
如有任何帮助,我们将不胜感激!
我认为问题来自位置检查(这很难阅读,因为它都在 if 语句中的一行上)。
让我们首先定义一个函数来检查一个人是否在给定的房子里:
def isInside(person, house):
"""
person is the dict with x1, y1, x2 and y2 for that person
house is the dict with x1, y1, x2 and y2 for that person
"""
# First we make sure we compare things in the right order
# You can skip that part if you are sure that in all cases x1 < x2 and y1 < y2
p_xmin = min(person["x1"], person["x2"])
p_xmax = max(person["x1"], person["x2"])
p_ymin = min(person["y1"], person["y2"])
p_ymax = max(person["y1"], person["y2"])
h_xmin = min(house["x1"], house["x2"])
h_xmax = max(house["x1"], house["x2"])
h_ymin = min(house["y1"], house["y2"])
h_ymax = max(house["y1"], house["y2"])
# Then you perform your checks. From what I understood,
# you want the result to be true if any corner of the person
# is inside the house's bounding box.
p_corners = [
(p_xmin, p_ymin),
(p_xmin, p_ymax),
(p_xmax, p_ymin),
(p_xmax, p_ymax)]
for corner in p_corners:
in_range_along_x = corner[0] < h_xmax and corner[0] > h_xmin
in_range_alond_y = corner[1] < h_ymax and corner[1] > h_ymin
if in_range_along_x and in_range_along_y:
return True
# If we get there, then the person is not inside that house
return False
您还可以修改上面的函数以使用人的边界框的中心而不是角,或者检查所有角是否都在里面。这是作为奖励的中心版本:
def centerIsInside(person, house):
"""
person is the dict with x1, y1, x2 and y2 for that person
house is the dict with x1, y1, x2 and y2 for that person
"""
# First we make sure we compare things in the right order
# You can skip that part if you are sure that in all cases x1 < x2 and y1 < y2
h_xmin = min(house["x1"], house["x2"])
h_xmax = max(house["x1"], house["x2"])
h_ymin = min(house["y1"], house["y2"])
h_ymax = max(house["y1"], house["y2"])
# We compute the center of the person:
p_xcenter = (person["x1"]+person["x2"])/2
p_ycenter = (person["y1"]+person["y2"])/2
# Then you perform your checks.
in_range_along_x = p_xcenter < h_xmax and corner[0] > p_xcenter
in_range_alond_y = p_ycenter < h_ymax and corner[1] > p_ycenter
if in_range_along_x and in_range_along_y:
return True
else:
return False
然后您可以使用该函数来执行检查,而不是那个长 if 语句:
# [...]
houses = [house1, house2, house3]
isinside_checks = []
for house in houses:
isinside_checks.append(isInside(person_coords, house))
if any(inside_checks):
print ("Person", num_person, ": True\n")
else:
print ("Person", num_person, ": False\n")
# [...]
您还可以修改 isInside
函数,使其根据参数执行不同类型的检查(任何角、中心、所有角...)