Anchor 的两种编程实现
- aspect ratios:高宽比率
假设 window 的尺寸为:\((w, h)\),锚框的尺寸为:\((w_1, h_1)\),则有:
\frac{w_1h_1}{wh} = s^2\\
\frac{h_1}{w_1} = \frac{h}{w} r
\end{cases}
\]
可以化简为:
w_s = \frac{w_1}{s} = \frac{w}{\sqrt{r}} \\
h_s = \frac{h_1}{s} = h \sqrt{r}
\end{cases}
\]
我们可以有两种编程实现方式:
1 \(w=h\)
w_s = \frac{w_1}{s} = \frac{w}{\sqrt{r}} = \text{round}(\sqrt{\frac{wh}{r}})\\
h_s = \frac{h_1}{s} = h \sqrt{r} = \sqrt{whr} = \text{round}(w_s r)
\end{cases}
\]
编程实现:
import numpy as np
class AnchorBase:
def __init__(self, base_size, scales, ratios):
self.scales = np.array(scales) #
self.ratios = np.array(ratios) #
self.num_anchors = len(self.ratios) * len(self.scales) # 锚框的个数
self.base_size = base_size # 滑动窗口的大小
if isinstance(base_size, int):
self._w, self._h = [base_size]*2
elif len(base_size) == 2:
self._w, self._h = base_size
elif len(base_size) == 1:
self._w, self._h = base_size*2
self._anchor = np.array([1, 1, self._w, self._h]) - 1
@property
def anchor(self):
return self._anchor
@anchor.setter
def anchor(self, new_anchor):
self._anchor = new_anchor
@property
def w(self):
'''
锚框的宽度
'''
return self.anchor[2] - self.anchor[0] + 1
@property
def h(self):
'''
锚框的高度
'''
return self.anchor[3] - self.anchor[1] + 1
@property
def size(self):
'''
锚框的面积
'''
return self.w * self.h
@property
def _whctrs(self):
"""
Return x center, and y center for an anchor (window). 锚框的中心坐标
"""
x_ctr = self.anchor[0] + 0.5 * (self.w - 1)
y_ctr = self.anchor[1] + 0.5 * (self.h - 1)
return np.array([x_ctr, y_ctr])
@staticmethod
def _coordinate(aspect, ctr):
'''
依据宽高组合计算锚框的坐标
'''
k = (aspect - 1) / 2
return np.concatenate([ctr - k, ctr + k], axis=1)
class AnchorRCNN(AnchorBase):
def __init__(self, base_size, scales, ratios):
super().__init__(base_size, scales, ratios)
self.anchors = self.gen_anchors()
@property
def ratio_aspects(self):
'''
依据 ratios 获取锚框的所有宽高组合
'''
size_ratios = self.size / self.ratios
ws = np.round(np.sqrt(size_ratios))
hs = np.round(ws * self.ratios)
return np.stack([ws, hs], axis=1)
@property
def ratio_anchors(self):
return self._coordinate(self.ratio_aspects, self._whctrs)
@property
def scale_aspects(self):
'''
依据 scales 获取锚框的所有宽高组合
'''
ws = self.w * self.scales
hs = self.h * self.scales
return np.stack([ws, hs], axis=1)
@property
def scale_anchors(self):
return self._coordinate(self.scale_aspects, self._whctrs)
def gen_anchors(self):
'''
获取最终的 base_anchors
'''
anchors = []
for anchor in self.ratio_anchors:
self.anchor = anchor
anchors.append(self.scale_anchors)
return np.concatenate(anchors)
scales = [8, 16, 32] # 尺度,面积比
ratios = [0.5, 1, 2] # window(滑动窗口) 与锚框的面积的比率(aspect ratios)
base_size = 16 # 滑动窗口的大小
self = AnchorRCNN(base_size, scales, ratios)
self.anchors
array([[ -84., -40., 99., 55.],
[-176., -88., 191., 103.],
[-360., -184., 375., 199.],
[ -56., -56., 71., 71.],
[-120., -120., 135., 135.],
[-248., -248., 263., 263.],
[ -36., -80., 51., 95.],
[ -80., -168., 95., 183.],
[-168., -344., 183., 359.]])
self.ratio_anchors
array([[-3. , 2.5, 18. , 12.5],
[ 0. , 0. , 15. , 15. ],
[ 2.5, -3. , 12.5, 18. ]])
2
\frac{w_1}{w} = \frac{s}{\sqrt{r}} = \text{round}(\frac{s}{\sqrt{r}})\\
\frac{h_1}{h} = s \sqrt{r} = \text{round}(\frac{w_1}{w} r)
\end{cases}
\]
记
S = [s_1, s_1, \cdots, s_m]\\
R = [r_1, r_2, \cdots, r_n]
\end{cases}
\]
则有(下面的运算均是元素级别的元素):
W = (\frac{s_i}{\sqrt{r_j}}) = \frac{S}{\sqrt{R}}\\
H = (s_i \sqrt{r_j}) = W \cdot R
\end{cases}
\]
class Anchor(AnchorBase):
def __init__(self, base_size, scales, ratios):
super().__init__(base_size, scales, ratios)
@property
def W(self):
'''
计算 w_1/ w
'''
W = self.scales[:, None] / np.sqrt(self.ratios)
return np.round(W)
@property
def H(self):
'''
计算 h_1/ h
'''
H = self.W * self.ratios
return np.round(H)
@property
def aspect(self):
'''
所有的宽高组合
'''
return np.stack([self.W.flatten(), self.H.flatten()], axis=1)
@property
def base_anchors(self):
return self._coordinate(self.aspect, self._whctrs)
@property
def anchors(self):
'''
获取最终的 base_anchors
'''
return self.base_anchors * np.array([self.w, self.h]*2)
scales = [8, 16, 32] # 尺度,面积比
ratios = [0.5, 1, 2] # window(滑动窗口) 与锚框的面积的比率(aspect ratios)
base_size = [16, 8]
self = Anchor(base_size, scales, ratios)
self.anchors
array([[ 40., 8., 200., 48.],
[ 64., 0., 176., 56.],
[ 80., -16., 160., 72.],
[ -56., -16., 296., 72.],
[ 0., -32., 240., 88.],
[ 40., -56., 200., 112.],
[-232., -56., 472., 112.],
[-128., -96., 368., 152.],
[ -56., -152., 296., 208.]])
Anchor 的两种编程实现的更多相关文章
- JAVA学习篇--JAVA两种编程模式控制
在Drp项目中,解说了两种编程模式Model 1和Model2.以下是对这两种模式的简单理解.以及因为Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对照学习一下. ...
- Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发WebFlux 支持两种编程风(姿)格(势) 使用@Controller这种基于注解
概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 R ...
- Edit Distance问题在两种编程范式下的求解
本文已授权 [Coding博客](https://blog.coding.net) 转载 前言 Edit Distance,中文叫做编辑距离,在文本处理等领域是一个重要的问题,以下是摘自于百度百科的定 ...
- [python]两种编程思维--面向过程和面向对象
例如:eg:炒一份西红柿鸡蛋 一.面向过程 面向过程的编程思维,如下 二.面向对象 制作一台炒菜机器人,然后告诉机器人做一道西红柿炒鸡蛋.在这里,我们直接面对的是机器人,而非炒菜的过程,所以这里机器人 ...
- EF三种编程方式的区别Database first ,Model first ,code first
首先对于EF中先出现的datebase first和model first两种编程方式,其的区别根据字面意思很容易能够理解. datebase first就是代表数据库优先,那么前提就是先创建数据 ...
- angular2系列教程(六)两种pipe:函数式编程与面向对象编程
今天,我们要讲的是angualr2的pipe这个知识点. 例子
- Arduino下LCD1602综合探究(上)——1602的两种驱动方式,如何使LCD的控制编程变得更简单
一.前言: LCD ( Liquid Crystal Display 的简称)液晶显示器,已经逐渐替代CRT成为主流的显示设备之一,因此也成为了单片机发烧友绕不过的话题之一:而LCD1602更是很多单 ...
- Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程
Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...
- [转] LBYL与EAFP两种防御性编程风格
检查数据可以让程序更健壮,用术语来说就是防御性编程.检查数据的时候,有这样的两种不同的风格.LBYL:Look Before You Leap EAFP:Easier to Ask Forgiven ...
随机推荐
- PHP二叉树
<?php /******************************************************** * 我写的PHP都是从C语言的数据结构中演化而来********* ...
- HTTP 协议报文解析
说明转载自https://blog.csdn.net/chf1142152101/article/details/74162755 本篇主要是为了记录HTTP中报文的格式,以便针对报文进行解析.首先会 ...
- jquery 学习(五) - CSS 操作
HTML + CSS 样式 /*CSS样式*/<style> body{ margin: 0; } div{ width: 100%; height: 2000px; background ...
- python 入门基础21 --面向对象_多态、内置方法、反射
内容: 1.接口思想 2.抽象类思想 3.多态 4.内置方法 5.反射 1.接口思想 建立关联的桥梁,方便管理代码 接口类:用来定义功能的类,位继承它的子类提供功能 该类的功能方法一般不需要实现体,实 ...
- 2017-2018-2 165X 『Java程序设计』课程每周成绩公布
2017-2018-2 165X 『Java程序设计』课程 每周成绩公布 本博客将跟随教学进度不定期更新,每次更新后将在课程群公布.如对成绩有疑问,请于公布成绩后的1天之内联系助教,进行审核确认. - ...
- cmake使用示例与整理总结
转自: http://blog.csdn.net/wzzfeitian/article/details/40963457/ 本文代码托管于github https://github.com/carl ...
- 【转载】Hadoop mapreduce 实现原理
1. 如何用通俗的方法解释MapReduce MapReduce是Google开源的三大技术之一,是对海量数据进行“分而治之”计算框架.为了简单的理解并讲述给客户理解.我们举下面的例子来说明. 首先 ...
- Linux系统打开core dump的配置【转】
什么是core dump core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.core du ...
- c# 界面自适应大小
采用在窗体事件SizeChanged里面代码控制大小和位置,达到自动适应窗体大小,这样做调整起来方便. private void FrmMain_SizeChanged(object sender, ...
- Ex 6_16 旧货销售问题_第七次作业
即可 子问题定义:定义数组B(S,j),其中 B(S,j)表示在子集S中结束位置为j的子问题的最大收益值,其中j的前一个地点有两种情况,第一种情况是某个拍卖会 另一种情况是从家里出发. 递归关系: 初 ...