非最大抑制-600学习网
600学习网终身会员188,所有资源无秘无压缩-购买会员
简介
你曾经使用过物体检测算法吗?如果是这样,很可能您使用了非最大抑制算法。也许这是你使用的深度学习模式的一部分,你甚至没有注意到。因为即使是非常复杂的算法也会面临这个问题,它们会多次识别同一个对象。今天,我想向您展示非最大抑制算法的工作原理,并提供一个python实现。首先,我将向您展示边界框是包围图像中检测到的对象的矩形。然后我将介绍非最大抑制的代码。该算法逐个删除冗余边界框。这是通过删除重叠超过阈值的框来实现的。边界框我们使用边界框来标记图像中标识感兴趣对象的部分。
在本例中,要识别的对象是正方形A中的大正方形。边界框始终是垂直矩形。因此,我们只需要存储所有边界框的左上角和右下角。
当使用目标检测方法时,同一目标常常在略微不同的区域被多次检测到。
在大多数情况下,我们只想检测一次对象。为此,我们通过应用非最大抑制来删除冗余边界框。非最大抑制现在,我们向您展示执行非最大抑制的完整功能代码,让您有一个概述。但别担心。我会给你看密码。
Def NMS(boxes,overlap Threshold=0.4):如果没有给定框,则#返回空列表
如果len(boxes)==0:返回〔〕x1=boxes〔:,0〕#左上角的x坐标y1=boxe〔:,1〕#右上角的y坐标x2=boxs〔::,2〕#x右下角的坐标y2=boxes〔:,3〕#
#计算边界框的面积并对边界进行排序
#框右下角的Y坐标
面积=(x2-x1+1)*(y2-y1+1)#需要加1
#开头所有方框的索引。
指数=np.arange(len(x1))
对于i,enumerate(boxes)中的框:#创建临时索引temp_indices=dices[dices!=i#找出相交正方形的坐标xx1=np.maximum(框[0],框[temp_ndices,0])yy1=np。最大值(框[1],框[temp_indices,1])xx2=np。最小值(框[2],框[temp_indices,2])yy2=np。minimum(box[3],box[temp_indices,3])#找出横框的宽度和高度w=np。最大(0,xx2-xx1+1)h=np。maximum(0,yy2-yy1+1)#计算重叠率overlay=(w*h)/面积[temp_indices]#如果实际边界帧与其他帧之间的重叠大于阈值,则删除其索引,如果为np。any(overlay)>restore:index=index[indexs!=I]#仅返回框[indexs]。其他索引的atype(int)
非最大抑制(NMS)函数接收一组帧,默认阈值为0.4。
def NMS(框,重叠阈值=0.4):
必须对框的数组进行组织,以便每行包含不同的边界框。
如果它们重叠得更多,将丢弃其中一个。重叠树阈值0.4意味着两个矩形可以共享其40%的面积。矩形的面积是通过宽度乘以高度来计算的。我们添加1是因为边界框在开始和结束坐标中都有一个像素。
面积=(x2-x1+1)*(y2-y1+1)
然后,我们为所有框创建索引。稍后,我们将逐个删除索引,直到只有对应于非重叠框的索引。
指数=np.arange(len(x1))
在循环中,我们遍历所有框。对于每个框,我们检查其与任何其他框的重叠是否大于阈值。如果是,我们将从索引列表中删除该框的索引。
我们创建一个包含box索引的索引,该索引不包含box[i]索引。
temp_索引=索引〔索引!=i]
为了计算重叠,我们
xx1=np.maximum(框[0],框[temp_indexs,0])yy1=np-maximum
这可能有点混乱,但零点在左上角。因此,我们可以选择”??”????选项????1.然后呢????最小值1,????2.温度????2以获得相交框的坐标。
然后计算相交框的宽度和高度。我们取最大值0和计算的宽度和高度,因为负值的宽度和高会干扰重叠计算。
w=np.最大值(0,xx2-xx1+1)h=np.最小值(0.yy2-yy1+1
重叠是相交框的面积除以边界框的面积。在我们的示例中,所有边界框的大小都相同,但该算法也适用于不同的大小。
重叠=(w*h)/面积〔温度指数〕
然后,如果框[i]和任何其他框之间的重叠大于主动变更,我们将从其余索引中排除索引i。
如果np.any(重叠)>侵入:索引=索引〔索引!=i]
然后,我们返回带有未删除索引的框。像素坐标必须是整数,因此我们仅为安全起见转换它们。
返回框〔索引〕.astype(int)
对于基于模板匹配的目标检测,您可能会问自己,我是如何得到这些边界框的。我使用了一种叫做模板匹配的简单技术。您只需要一个图像和一个模板,即您要搜索的对象。我们的形象将是正方形A。
我们的模板将是图像中间的正方形。
请注意,模板的方向和大小(以像素为单位)必须与图像中要检测的对象大致相同。
我们需要opencv。如果没有,可以将其安装在终端中。
pip安装opencv-python
我们导入cv2。
导入cv2
要执行模板匹配并从中生成边界框,我们可以使用以下函数。
定义bounding_box(图像,模板):(tH,tW)=模板。shape[:2]#获取模板图像的高度和宽度Gray=cv2.cvtColor(image,0)#将图像转换为灰度模板Gray=cv2.cvt Color(template,0)#将模板转换为灰度
结果=cv2.matchTemplate(imageGray,templateGray,cv2.TM_CCOEFF_NORMED)#模板匹配返回相关姓(y1,x1)=np。其中(结果>=阈值)#检测到对象,其中相关姓高于阈值框=np。zeros((len(y1),4))#构造一个零数组x2=x1+tW#计算模板的宽度x2 y2=y1+tH#计算y2和模板的高度#填充边框数组框〔:,0〕=x1框〔:1〕=y1框〔:.2〕=x2框〔,3〕=y2返回框。astype(int)
cv2.matchTemplate函数返回图像的不同部分与模板之间的相关姓。
然后,我们选择图像中相关姓高于阈值的部分。
(y1,x1)=np.其中(结果>=侵入)
我们还需要一个函数来将边界框绘制到图像上。
def绘制_边界_框(图像,框):
对于框中的框:image=cv2.矩形(copy.depcopy(image),框〔:2〕,框〔2:〕,(255,0,0),3)返回图像
完整的代码
导入cv2
导入pyautogui
导入pyautogui
导入cv2
将numpy导入为np
导入操作系统
导入时间
将matplotlib.pyplot导入为plt
导入副本
def NMS(框,重叠阈值=0.4):
#如果没有给出框,则返回空列表
如果len(boxes)==0:
返回〔〕
X1=方框〔:,0〕#x左上角坐标
Y1=框〔:,1〕#左上角的y坐标
X2=方框〔:,2〕#右下角的x坐标
Y2=方框〔:,3〕#右下角的y坐标
#计算边界框的面积并对边界进行排序
#框右下角的Y坐标
面积=(x2-x1+1)*(y2-y1+1)#需要加1
#开头所有方框的索引。
指数=np.arange(len(x1))
对于i,枚举(框)中的框:#创建临时索引temp_indices=dices[dices!=I#找出相交正方形的坐标xx1=np.maximum(框[0],框[temp_dices,0])yy1=np-maximumframe w=np.maximum(0,xx2-xx1+1)h=np.mmaximum(1,yy2-yy1+1)#计算重叠率overlay=(w*h)/面积[temp_indices]#如果实际边界帧与其他帧之间的重叠大于阈值,如果np.any(overlay)>restore,则删除其索引
#仅返回具有其他索引的框
返回框〔索引〕.astype(int)
定义边界_框(图像.模板):
(tH,tW)=模板。shape[:2]#获取模板图像的高度和宽度Gray=cv2.cvtColor(image,0)#将图像转换为灰度模板Gray=cv2.cvt Color(template,0)#将模板转换为灰度
结果=cv2.matchTemplate(imageGray,templateGray,cv2.TM_CCOEFF_NORMED)#模板匹配返回相关姓(y1,x1)=np.其中(结果>=阈值)#检测到对象,其中相关姓高于阈值框=np.零((len(y1),4))#构造一个零数组x2=x1+tW#计算模板的宽度x2 y2=y1+tH#计算y2和模板的高度#填充边框数组框〔:,0〕=x1框〔:1〕=y1框〔:2〕=x2框〔,3〕=y2返回框。astype(int)
def draw_bounding_boxes(image,boxes):对于框中的框:image=cv2.矩形(copy.depcopy(image),box[:2],box[2:],(255,0,0),3)返回图像
如果__name__==”__main__”:
睡眠时间(2)
阈值=0.8837#用于识别对象的相关阈值
模板_diamonds=plt。立即(r”templates/ace_diamonds_plant_template.jpg”)ace_dianmonds_rotated=plt。immediate(r”images/ace_diamonds_table_rotated.jpg”)box_redundant=bounding_boxes(ace_ddiamonds_rotated,template_diamonds)#计算边界框boxes=NMS(box_redundant)#删除冗余边界框overapping_BB_image=draw_boundingboxes使用所有冗余边框plt.show()plt.imshow(segmented__image)plt.show()
结论
我们可以使用非最大抑制来删除多余的边界框。它们是多余的,因为它们多次标记同一对象。
NMS算法使用相交三角形的面积来计算三角形之间的重叠。如果边界框与阈值以上的任何其他边界框重叠,则边界框将被删除。
600学习网 » 非最大抑制-600学习网