yolov3 先验框讲解与代码实现

不同尺度先验框与目标物体大小

随着输出的特征图的数量和尺度的变化,先验框的尺寸也需要相应的调整。YOLO2已经开始采用K-means聚类得到先验框的尺寸,YOLO3延续了这种方法,为每种下采样尺度设定3种先验框,总共聚类出9种尺寸的先验框。在COCO数据集这9个先验框是:
(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。

分配上,在最小的13 * 13特征图上(有最大的感受野)应用较大的先验框(116x90),(156x198),(373x326),适合检测较大的对象。
中等的26 * 26特征图上(中等感受野)应用中等的先验框(30x61),(62x45),(59x119),适合检测中等大小的对象。
较大的52 * 52特征图上(较小的感受野)应用较小的先验框(10x13),(16x30),(33x23),适合检测较小的对象。

在这里插入图片描述 图4 特征图与先验框

感受一下9种先验框的尺寸,下图中蓝色框为聚类得到的先验框。黄色框式ground truth,红框是对象中心点所在的网格。

在这里插入图片描述

作者:X猪
链接:https://www.jianshu.com/p/d13ae1055302
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码实现

相关图片

输入原图

在这里插入图片描述

13x13特征图先验框(绿色)

在这里插入图片描述

26x26特征图先验框(浅蓝色)

在这里插入图片描述

52x52特征图先验框(黄色)

在这里插入图片描述

代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import cv2
def showPrioriBox():
	#输入图片尺寸
	INPUT_SIZE = 416

	mask52=	[0,1,2]
	mask26=	[3,4,5]
	mask13=	[6,7,8]
	anchors=[ 10,13, 16,30, 33,23,
			  30,61, 62,45, 59,119,
			  116,90, 156,198, 373,326]
	FEATURE_MAP_SIZE=26
	SHOW_ALL_FLAG  = True  # 显示所有的方框
	GRID_SHOW_FLAG =True

	# cap = cv2.VideoCapture("street.jpg")
	picPath = './street.jpg'
	picName = picPath.split('/')[-1]
	img = cv2.imread(picPath)
	print("original img.shape: ",img.shape)  # (1330, 1330, 3)
	img = cv2.resize(img,(INPUT_SIZE, INPUT_SIZE))

	# 显示网格
	if GRID_SHOW_FLAG:
		height, width, channels = img.shape
		GRID_SIZEX =  int(INPUT_SIZE/FEATURE_MAP_SIZE)
		for x in range(0, width - 1, GRID_SIZEX):
			cv2.line(img, (x, 0), (x, height), (150, 150, 255), 1, 1)  # x grid

		GRID_SIZEY = int(INPUT_SIZE / FEATURE_MAP_SIZE)
		for y in range(0, height - 1, GRID_SIZEY):
			cv2.line(img, (0, y), (width, y), (150, 150, 255), 1, 1)  # x grid
		# END:显示网格
		# cv2.imshow('Hehe', img)
		# cv2.imwrite('./' + picName.split('.')[0] + '_grid.' + picName.split('.')[1], img)

	if SHOW_ALL_FLAG or FEATURE_MAP_SIZE==13:
		for ele in mask13:
			# print(ele)
			cv2.rectangle(img, (
			(int(INPUT_SIZE * 0.5 - 0.5*anchors[ ele * 2]), int(INPUT_SIZE * 0.5 -  0.5*anchors[ ele * 2 + 1]))),
						  ((int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2]),
							int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2 + 1]))), (0, 255-ele*10, 0), 2)
		# cv2.imwrite('./' + picName.split('.')[0] + '_saveMask13.' + picName.split('.')[1], img)

	if SHOW_ALL_FLAG or FEATURE_MAP_SIZE==26:
		for ele in mask26:
			# print(ele)
			cv2.rectangle(img, (
			(int(INPUT_SIZE * 0.5 - 0.5*anchors[ ele * 2]), int(INPUT_SIZE * 0.5 -  0.5*anchors[ ele * 2 + 1]))),
						  ((int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2]),
							int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2 + 1]))), (255, 255-ele*10, 0), 2)
		# cv2.imwrite('./' + picName.split('.')[0] + '_saveMask26.' + picName.split('.')[1], img)

	if SHOW_ALL_FLAG or FEATURE_MAP_SIZE==52:
		for ele in mask52:
			# print(ele)
			cv2.rectangle(img, (
			(int(INPUT_SIZE * 0.5 - 0.5*anchors[ ele * 2]), int(INPUT_SIZE * 0.5 -  0.5*anchors[ ele * 2 + 1]))),
						  ((int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2]),
							int(INPUT_SIZE * 0.5 + 0.5*anchors[ ele * 2 + 1]))), (0, 255-ele*10, 255), 1)
		# cv2.imwrite('./' + picName.split('.')[0] + '_saveMask52.' + picName.split('.')[1], img)


	cv2.imwrite('./' + picName.split('.')[0] + '_allSave.' + picName.split('.')[1], img)

	cv2.imshow('img', img)
	while cv2.waitKey(1000) != 27:  # loop if not get ESC.
		if cv2.getWindowProperty('img', cv2.WND_PROP_VISIBLE) <= 0:
			break
	cv2.destroyAllWindows()

if __name__ == '__main__':
    showPrioriBox()
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值