边界框:就是定义物体实际位置的一个概念——通常为矩形框,有时也可以取多边形框。
如下图所示:
其中的红色框线就是我们的边界框——在目标检测中一般认为真实框就是边界框, 而预测框与锚框对应。
上图中的边界框要想表示出来,可以有两种表示方式:
现在基本了解了边界框的含义和表示,那么我们来用代码绘制一下吧!
bbox: 即 Bounding box
import numpy as np # 可能用到的数据值计算库
import os # 可能用到的文件操作
import matplotlib.pyplot as plt # 图形绘制
import matplotlib.patches as patches # 添加矩形框
import matplotlib.image as image # 读取图像数据
这里提供一个方法,实现两种表示形式bbox的转换——输入统一为xyxy,但转换后输出可以是xyxy与xywh两者之一。
def BoundingBox_Denote(bbox=[], mode=True):
'''边界框的表示形式的转换
bbox: 包含(x1, y1, x2, y2)四个位置信息的数据格式
mode: 边界框数据表示的模式
True: to (x1,y1,x2,y2)
False: to (x,y,w,h)
return: 返回形式转换后的边界框数据
'''
denote_bbox = [] # 转换表示的边界框
if mode is True: # 保持原形式
denote_bbox = bbox
else: # 转换为(center_x, center_y, w, h)
center_x = (bbox[0]+bbox[2]) / 2.0
center_y = (bbox[1]+bbox[3]) / 2.0
w = bbox[2] - bbox[0]
h = bbox[3] - bbox[1]
denote_bbox = [center_x, center_y, w, h]
# 返回表示转换的边界框表示
denote_bbox = np.asarray(denote_bbox, dtype='float32')
return denote_bbox
使用matplotlib重点patchesAPI来绘制矩形——也可以换opencv等其它方法绘制。
def draw_rectangle(bbox=[], mode=True, color='k', fill=False):
'''绘制矩形框
bbox:边界框数据(默认框数据不超过图片边界)
mode: 边界框数据表示的模式
True: to (x1,y1,x2,y2)
False: to (x,y,w,h)
color: 边框颜色
fill: 是否填充
'''
if mode is True: # to (x1,y1,x2,y2)
x = bbox[0]
y = bbox[1]
w = bbox[2] - bbox[0] + 1
h = bbox[3] - bbox[1] + 1
else: # to (x,y,w,h)
# 默认绘制的框不超出边界
x = bbox[0] - bbox[2] / 2.0
y = bbox[1] - bbox[3] / 2.0
w = bbox[2]
h = bbox[3]
# 绘制边界框
# patches.Rectangle需要传入左上角坐标、矩形区域的宽度、高度等参数
# 获取绘制好的图形的返回句柄——用于添加到当前的图像窗口中
rect = patches.Rectangle((x, y), w, h,
linewidth=1, # 线条宽度
edgecolor=color, # 线条颜色
facecolor='y', #
fill=fill, linestyle='-')
return rect
def img_draw_bbox(bbox=[10, 20, 90, 100], mode=True):
'''将边界框绘制到实际图片上
bbox: 需要绘制的边界框
mode: 边界框数据表示的转换模式
True: to (x1,y1,x2,y2)
False: to (x,y,w,h)
'''
fig = plt.figure(figsize=(12, 8))
ax = plt.gca() # 窗口句柄
# 图片路径
img_path = os.path.join(os.getcwd(), 'img', '1.jpg')
img = image.imread(img_path) # 读取图片数据
plt.imshow(img) # 展示图片
# 边界框数据转换
denote_mode = mode # 边界框表示形式——确定数据格式
# 经过转换后的边界框数据
bbox1 = BoundingBox_Denote(bbox=bbox, mode=denote_mode)
# 绘制表示模式2的边界框
rect1 = draw_rectangle(bbox=bbox1, mode=denote_mode, color='r')
ax.add_patch(rect1) # 将矩形添加到当前的图片上
plt.show()
# 边界框真实数据
test_bbox = [160, 60, 460, 260]
# 边界框数据表示模式——输入的bbox数据必须是[x1,y1,x2,y2]
# True: to (x1,y1,x2,y2)
# False: to (x,y,w,h)
# denote_mode = True
denote_mode = False
# 测试边界框的转换是否成功
test_bbox_denote(bbox=test_bbox, mode=denote_mode)
# 测试边界框的绘制
img_draw_bbox(bbox=test_bbox, mode=denote_mode)
相关链接(持续更新)
目标检测(二)——锚框总结与代码实现(可完整实现)
目标检测(三)——IoU总结与代码实现(可完整实现)