如何知道边界框(矩形)是否位于另一个边界框(矩形)内?
How to know if a bounding box(rectangle) lies inside another bounding box(rectangle)?
我正在尝试获取外框内的框(坐标)。我已经完成了使用 intersection over union 方法,我希望其他方法也能这样做。
还有,能告诉我如何比较这两个内盒吗?
您可以使用 contours hierarchy。
在您发布的图片中,内部矩形是具有父项和子项的轮廓(当使用 findContours
和 RETR_TREE
标志时)。
这是一个代码示例:
import cv2
# Read input image
img = cv2.imread("boxes.png")
# Convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply threshold
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Find contours and hierarchy
cnts, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:] # Use [-2:] for OpenCV 3, 4 compatibility.
# Draw all contours with green color for testing
cv2.drawContours(img, cnts, -1, (0, 255, 0))
# Hierarchy Representation in OpenCV
# So each contour has its own information regarding what hierarchy it is,
# who is its child, who is its parent etc.
# OpenCV represents it as an array of four values : [Next, Previous, First_Child, Parent]
# Iterate contours and hierarchy:
for c, h in zip(cnts, hier[0]):
# Check if contour has one partent and one at least on child:
if (h[3] > 0) and (h[2] > 0):
# Get bounding rectange
x, y, w, h = cv2.boundingRect(c)
# Draw red rectange for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness=1)
# Show result for testing
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
更新:
我在上面的代码中有一个错误(使用 > 0
而不是 >= 0
)。
我们还需要验证父对象是否有父对象。
好像有点矫枉过正了...
# Iterate contours and hierarchy:
for c, h in zip(cnts, hier[0]):
# Check if contour has one partent and one at least on child:
if (h[3] >= 0) and (h[2] >= 0):
# Get the partent from the hierarchy
hp = hier[0][h[3]]
# Check if the parent has a parent:
if hp[3] >= 0:
# Get bounding rectange
x, y, w, h = cv2.boundingRect(c)
# Draw red rectange for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness=1)
通过比较边界框和内部框的左上角和右下角的坐标,很容易知道后者是否在前者内部。
下面的代码是一个只有一个边界框和一个内框的简单例子:
# Bounding box
boundb = {
'x': 150,
'y': 150,
'height': 50,
'width': 100
}
# Inner box
innerb = {
'x': 160,
'y': 160,
'height': 25,
'width': 25
}
# If top-left inner box corner is inside the bounding box
if boundb['x'] < innerb['x'] and boundb['y'] < innerb['y']:
# If bottom-right inner box corner is inside the bounding box
if innerb['x'] + innerb['width'] < boundb['x'] + boundb['width'] \
and innerb['y'] + innerb['height'] < boundb['y'] + boundb['height']:
print('The entire box is inside the bounding box.')
else:
print('Some part of the box is outside the bounding box.')
我正在尝试获取外框内的框(坐标)。我已经完成了使用 intersection over union 方法,我希望其他方法也能这样做。
还有,能告诉我如何比较这两个内盒吗?
您可以使用 contours hierarchy。
在您发布的图片中,内部矩形是具有父项和子项的轮廓(当使用 findContours
和 RETR_TREE
标志时)。
这是一个代码示例:
import cv2
# Read input image
img = cv2.imread("boxes.png")
# Convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply threshold
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Find contours and hierarchy
cnts, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:] # Use [-2:] for OpenCV 3, 4 compatibility.
# Draw all contours with green color for testing
cv2.drawContours(img, cnts, -1, (0, 255, 0))
# Hierarchy Representation in OpenCV
# So each contour has its own information regarding what hierarchy it is,
# who is its child, who is its parent etc.
# OpenCV represents it as an array of four values : [Next, Previous, First_Child, Parent]
# Iterate contours and hierarchy:
for c, h in zip(cnts, hier[0]):
# Check if contour has one partent and one at least on child:
if (h[3] > 0) and (h[2] > 0):
# Get bounding rectange
x, y, w, h = cv2.boundingRect(c)
# Draw red rectange for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness=1)
# Show result for testing
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
更新:
我在上面的代码中有一个错误(使用 > 0
而不是 >= 0
)。
我们还需要验证父对象是否有父对象。
好像有点矫枉过正了...
# Iterate contours and hierarchy:
for c, h in zip(cnts, hier[0]):
# Check if contour has one partent and one at least on child:
if (h[3] >= 0) and (h[2] >= 0):
# Get the partent from the hierarchy
hp = hier[0][h[3]]
# Check if the parent has a parent:
if hp[3] >= 0:
# Get bounding rectange
x, y, w, h = cv2.boundingRect(c)
# Draw red rectange for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness=1)
通过比较边界框和内部框的左上角和右下角的坐标,很容易知道后者是否在前者内部。
下面的代码是一个只有一个边界框和一个内框的简单例子:
# Bounding box
boundb = {
'x': 150,
'y': 150,
'height': 50,
'width': 100
}
# Inner box
innerb = {
'x': 160,
'y': 160,
'height': 25,
'width': 25
}
# If top-left inner box corner is inside the bounding box
if boundb['x'] < innerb['x'] and boundb['y'] < innerb['y']:
# If bottom-right inner box corner is inside the bounding box
if innerb['x'] + innerb['width'] < boundb['x'] + boundb['width'] \
and innerb['y'] + innerb['height'] < boundb['y'] + boundb['height']:
print('The entire box is inside the bounding box.')
else:
print('Some part of the box is outside the bounding box.')