使用yolo3实现图片中的数字检测与识别(二):边界框和锚框介绍

技术凯 2021-04-30 00:31:47 9736

  上篇文章,我们介绍了数字检测任务的数据集制作过程,接下来,我们就可以搭建模型,导入数据并开始训练了。但是在此之前,我们得先了解一些目标检测算法的基础概念。

一、边界框

  目标检测的任务首先是检测物体的位置,所以我们必须约定一种表示位置的方法。通常我们使用包含目标的矩形框位置来描述目标的位置,这个矩形框就是边界框(bounding box, bbox)。图像处理领域通常使用原点在左上角的笛卡尔坐标系表示某个点的位置,这样,边界框的表示方法通常就有以下两种:

  1. 使用边界框左上角和右下角的坐标描述边界框的位置。即(x1,y1,x2,y2),x1,y1是边界框左上角的坐标,x2,y2是边界框右下角的坐标。

  2. 使用边界框左上角的坐标以及边界框的长宽来描述位置。即(x,y,w,h),x,y是边界框左上角的坐标,w,h是边界框的宽和长

  在同一个项目中,为了避免麻烦,我们最好使用同一种表示方法。下面将通过python实现在图像中使用边界框标注物体。

  首先,我们打开上篇文章中在AiStudio中创建的项目,该项目中保存了我们标注好的数据集,我们使用以下代码对数据集进行解压:

!unzip -d /home/aistudio/work/ /home/aistudio/data/data84373/number_detection_V1.zip

需要注意的是,在Aistudio的Notebook中使用Linux命令行代码时需要加'!'。其次,我们上篇文章中导入的数据有可能为中文名称,我们最好将其改为英文名称,比如我将其改成了'number_detection_V1'。

定义绘制边界框的程序:

#定义一个绘制矩形框的函数
#输入参数依此为:绘制的目标图像、边界框的坐标以及框的颜色
def draw_rect(pic,bbox,color):
    box=patches.Rectangle((bbox[0],bbox[1]),bbox[2]-bbox[0],bbox[3]-bbox[1],fill=False,edgecolor=color)
    axis=pic.axes
    axis.add_patch(box)

需要注意的是,这个项目使用的边界框表示方式为第一种方法,即使用两组坐标来表示边界框的位置,因为我们可以从之前导入的数据文件中看出,我们标注的位置信息以这种方式记录了下来:

接着,我们显示一张示例图片:

filename='/home/aistudio/work/DatasetId_158445_1619452569/7.jpeg'

file=imread(filename)
pic=plt.imshow(file)

运行结果:

定义两组边界框的位置坐标:

#添加边界框坐标
bbox1=[656,178,1229,899]
bbox2=[1549,178,1904,704]

然后运行边界框绘制函数,绘制两个边界框:

draw_bbox(pic,bbox1,'red')
draw_bbox(pic,bbox2,'blue')

运行结果:

完整代码如下:

import matplotlib.pyplot as plt
from matplotlib.image import imread
import matplotlib.patches as patches
import matplotlib.axes

#定义一个绘制矩形框的函数
#输入参数依此为:绘制的目标图像、边界框的坐标以及框的颜色
def draw_rect(pic,bbox,color):
    box=patches.Rectangle((bbox[0],bbox[1]),bbox[2]-bbox[0],bbox[3]-bbox[1],fill=False,edgecolor=color)
    axis=pic.axes
    axis.add_patch(box)

filename='/home/aistudio/work/DatasetId_158445_1619452569/7.jpeg'

file=imread(filename)
pic=plt.imshow(file)

#添加边界框坐标
bbox1=[656,178,1229,899]
bbox2=[1549,178,1904,704]

draw_bbox(pic,bbox1,'red')
draw_bbox(pic,bbox2,'blue')
二、锚框

  使用目标检测算法检测目标位置时,需要在图像中采样一系列区域,然后逐个判断每个区域中是否包含目标,每个目标检测模型的采样思路一般来说都不相同。对于我们本项目使用的yolo v3算法来说,它的基本思路是以图像中的某一个像素点为中心,创建一系列矩形框,然后判断每个矩形框是否包含目标以及包含了目标的多少部分,这里的一系列矩形框就称为锚框(anchor box)。产生锚框的基本思路是:

  1. 确定一个像素点作为锚框的中心,其坐标是c=(x,y);
  2. 确定一个基准长度l0;
  3. 确定一系列尺寸系数s和宽高比r,用于标定产生的一系列锚框的形状和大小,这一系列锚框的真实尺寸可以通过以下公式计算:

下面,我们将以上思路转换为python代码:
首先,需要定义一个绘制矩形框的函数。

#定义一个绘制矩形框的函数
#输入参数依此为:绘制的目标图像、矩形框的坐标以及框的颜色
def draw_rect(pic,pos,color):
    box=patches.Rectangle((pos[0],pos[1]),pos[2]-pos[0],pos[3]-pos[1],fill=False,edgecolor=color)
    axis=pic.axes
    axis.add_patch(box)

接着,我们定义绘制锚框的函数,需要注意的是,我们在编写此函数时需要加入约束,防止锚框超出图像显示范围。

#定义绘制一些列锚框的函数
#输入参数依此为:需要加锚框的图像、中心坐标、尺寸系数、宽高比、图像的尺寸
def draw_abox(pic,c,l0,s,r,img_size):
    for scale in s:
        for ratio in r:
            # 锚框的尺寸
            w=l0*scale*math.sqrt(ratio)
            h=l0*scale/math.sqrt(ratio)
            # 加入约束,防止锚框超出显示范围
            img_h=img_size[0]
            img_w=img_size[1]
            x1=max(c[0]-w/2.0,0.0)
            y1=max(c[1]-h/2.0,0,0)
            x2=min(c[0]+w/2.0,img_w)
            y2=min(c[1]+h/2.0,img_w)
            abox=[x1,y1,x2,y2]
            # 绘制锚框
            draw_rect(pic,abox,'blue')

开始绘制锚框,为了方便对比,我们这次也将目标的真实边界框绘制出来,边界框用红色框来表示,锚框使用蓝色框表示。

# 开始绘制锚框
# 显示一张示例图并加上真实的边界框
filename='/home/aistudio/work/DatasetId_158445_1619452569/7.jpeg'

file=imread(filename)
pic=plt.imshow(file)

#添加边界框坐标
bbox1=[656,178,1229,899]
bbox2=[1549,178,1904,704]

draw_rect(pic,bbox1,'red')
draw_rect(pic,bbox2,'red')

图像中加入真实边界框的效果为:

接着,绘制锚框

#绘制锚框
img_size=file.shape;
center=[942.5,538.5]
l0=300
s=[2.0]
r=[0.5,1,2]
draw_abox(pic,center,l0,s,r,img_size)

绘制出来的效果为:

完整代码如下:

import matplotlib.pyplot as plt
from matplotlib.image import imread
import matplotlib.patches as patches
import matplotlib.axes
import math

#定义一个绘制矩形框的函数
#输入参数依此为:绘制的目标图像、矩形框的坐标以及框的颜色
def draw_rect(pic,pos,color):
    box=patches.Rectangle((pos[0],pos[1]),pos[2]-pos[0],pos[3]-pos[1],fill=False,edgecolor=color)
    axis=pic.axes
    axis.add_patch(box)

#定义绘制一些列锚框的函数
#输入参数依此为:需要加锚框的图像、中心坐标、尺寸系数、宽高比、图像的尺寸
def draw_abox(pic,c,l0,s,r,img_size):
    for scale in s:
        for ratio in r:
            # 锚框的尺寸
            w=l0*scale*math.sqrt(ratio)
            h=l0*scale/math.sqrt(ratio)
            # 加入约束,防止锚框超出显示范围
            img_h=img_size[0]
            img_w=img_size[1]
            x1=max(c[0]-w/2.0,0.0)
            y1=max(c[1]-h/2.0,0,0)
            x2=min(c[0]+w/2.0,img_w)
            y2=min(c[1]+h/2.0,img_w)
            abox=[x1,y1,x2,y2]
            # 绘制锚框
            draw_rect(pic,abox,'blue')

# 开始绘制锚框
# 显示一张示例图并加上真实的边界框
filename='/home/aistudio/work/DatasetId_158445_1619452569/7.jpeg'

file=imread(filename)
pic=plt.imshow(file)

#添加边界框坐标
bbox1=[656,178,1229,899]
bbox2=[1549,178,1904,704]

draw_rect(pic,bbox1,'red')
draw_rect(pic,bbox2,'red')

#绘制锚框
img_size=file.shape;
center=[942.5,538.5]
l0=300
s=[2.0]
r=[0.5,1,2]
draw_abox(pic,center,l0,s,r,img_size)
三、总结

  本篇文章我们为大家介绍了目标检测算法的一些基础知识,包括边界框(bbox)和锚框(anchor box)。在目标检测任务中我们将产生的锚框作为候选区域,和目标的真实边界框进行对比,选出与真实框重合度最高的那一个锚框,进行微调之后作为座中预测位置的边界框。那么我们如何衡量边界框与每一个锚框之间的重合度呢,关于这个内容,我们将在下篇文章中进行讨论。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 91 7 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
技术凯
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区