• aspect ratios:高宽比率

假设 window 的尺寸为:\((w, h)\),锚框的尺寸为:\((w_1, h_1)\),则有:

\[\begin{cases}
\frac{w_1h_1}{wh} = s^2\\
\frac{h_1}{w_1} = \frac{h}{w} r
\end{cases}
\]

可以化简为:

\[\begin{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\)

\[\begin{cases}
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}
\]

编程实现:

  1. import numpy as np
  2. class AnchorBase:
  3. def __init__(self, base_size, scales, ratios):
  4. self.scales = np.array(scales) #
  5. self.ratios = np.array(ratios) #
  6. self.num_anchors = len(self.ratios) * len(self.scales) # 锚框的个数
  7. self.base_size = base_size # 滑动窗口的大小
  8. if isinstance(base_size, int):
  9. self._w, self._h = [base_size]*2
  10. elif len(base_size) == 2:
  11. self._w, self._h = base_size
  12. elif len(base_size) == 1:
  13. self._w, self._h = base_size*2
  14. self._anchor = np.array([1, 1, self._w, self._h]) - 1
  15. @property
  16. def anchor(self):
  17. return self._anchor
  18. @anchor.setter
  19. def anchor(self, new_anchor):
  20. self._anchor = new_anchor
  21. @property
  22. def w(self):
  23. '''
  24. 锚框的宽度
  25. '''
  26. return self.anchor[2] - self.anchor[0] + 1
  27. @property
  28. def h(self):
  29. '''
  30. 锚框的高度
  31. '''
  32. return self.anchor[3] - self.anchor[1] + 1
  33. @property
  34. def size(self):
  35. '''
  36. 锚框的面积
  37. '''
  38. return self.w * self.h
  39. @property
  40. def _whctrs(self):
  41. """
  42. Return x center, and y center for an anchor (window). 锚框的中心坐标
  43. """
  44. x_ctr = self.anchor[0] + 0.5 * (self.w - 1)
  45. y_ctr = self.anchor[1] + 0.5 * (self.h - 1)
  46. return np.array([x_ctr, y_ctr])
  47. @staticmethod
  48. def _coordinate(aspect, ctr):
  49. '''
  50. 依据宽高组合计算锚框的坐标
  51. '''
  52. k = (aspect - 1) / 2
  53. return np.concatenate([ctr - k, ctr + k], axis=1)
  54. class AnchorRCNN(AnchorBase):
  55. def __init__(self, base_size, scales, ratios):
  56. super().__init__(base_size, scales, ratios)
  57. self.anchors = self.gen_anchors()
  58. @property
  59. def ratio_aspects(self):
  60. '''
  61. 依据 ratios 获取锚框的所有宽高组合
  62. '''
  63. size_ratios = self.size / self.ratios
  64. ws = np.round(np.sqrt(size_ratios))
  65. hs = np.round(ws * self.ratios)
  66. return np.stack([ws, hs], axis=1)
  67. @property
  68. def ratio_anchors(self):
  69. return self._coordinate(self.ratio_aspects, self._whctrs)
  70. @property
  71. def scale_aspects(self):
  72. '''
  73. 依据 scales 获取锚框的所有宽高组合
  74. '''
  75. ws = self.w * self.scales
  76. hs = self.h * self.scales
  77. return np.stack([ws, hs], axis=1)
  78. @property
  79. def scale_anchors(self):
  80. return self._coordinate(self.scale_aspects, self._whctrs)
  81. def gen_anchors(self):
  82. '''
  83. 获取最终的 base_anchors
  84. '''
  85. anchors = []
  86. for anchor in self.ratio_anchors:
  87. self.anchor = anchor
  88. anchors.append(self.scale_anchors)
  89. return np.concatenate(anchors)
  1. scales = [8, 16, 32] # 尺度,面积比
  2. ratios = [0.5, 1, 2] # window(滑动窗口) 与锚框的面积的比率(aspect ratios)
  3. base_size = 16 # 滑动窗口的大小
  4. self = AnchorRCNN(base_size, scales, ratios)
  5. self.anchors
  1. array([[ -84., -40., 99., 55.],
  2. [-176., -88., 191., 103.],
  3. [-360., -184., 375., 199.],
  4. [ -56., -56., 71., 71.],
  5. [-120., -120., 135., 135.],
  6. [-248., -248., 263., 263.],
  7. [ -36., -80., 51., 95.],
  8. [ -80., -168., 95., 183.],
  9. [-168., -344., 183., 359.]])
  1. self.ratio_anchors
  1. array([[-3. , 2.5, 18. , 12.5],
  2. [ 0. , 0. , 15. , 15. ],
  3. [ 2.5, -3. , 12.5, 18. ]])

2

\[\begin{cases}
\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}
\]

\[\begin{cases}
S = [s_1, s_1, \cdots, s_m]\\
R = [r_1, r_2, \cdots, r_n]
\end{cases}
\]

则有(下面的运算均是元素级别的元素):

\[\begin{cases}
W = (\frac{s_i}{\sqrt{r_j}}) = \frac{S}{\sqrt{R}}\\
H = (s_i \sqrt{r_j}) = W \cdot R
\end{cases}
\]

  1. class Anchor(AnchorBase):
  2. def __init__(self, base_size, scales, ratios):
  3. super().__init__(base_size, scales, ratios)
  4. @property
  5. def W(self):
  6. '''
  7. 计算 w_1/ w
  8. '''
  9. W = self.scales[:, None] / np.sqrt(self.ratios)
  10. return np.round(W)
  11. @property
  12. def H(self):
  13. '''
  14. 计算 h_1/ h
  15. '''
  16. H = self.W * self.ratios
  17. return np.round(H)
  18. @property
  19. def aspect(self):
  20. '''
  21. 所有的宽高组合
  22. '''
  23. return np.stack([self.W.flatten(), self.H.flatten()], axis=1)
  24. @property
  25. def base_anchors(self):
  26. return self._coordinate(self.aspect, self._whctrs)
  27. @property
  28. def anchors(self):
  29. '''
  30. 获取最终的 base_anchors
  31. '''
  32. return self.base_anchors * np.array([self.w, self.h]*2)
  1. scales = [8, 16, 32] # 尺度,面积比
  2. ratios = [0.5, 1, 2] # window(滑动窗口) 与锚框的面积的比率(aspect ratios)
  3. base_size = [16, 8]
  4. self = Anchor(base_size, scales, ratios)
  5. self.anchors
  1. array([[ 40., 8., 200., 48.],
  2. [ 64., 0., 176., 56.],
  3. [ 80., -16., 160., 72.],
  4. [ -56., -16., 296., 72.],
  5. [ 0., -32., 240., 88.],
  6. [ 40., -56., 200., 112.],
  7. [-232., -56., 472., 112.],
  8. [-128., -96., 368., 152.],
  9. [ -56., -152., 296., 208.]])

Anchor 的两种编程实现的更多相关文章

  1. JAVA学习篇--JAVA两种编程模式控制

    在Drp项目中,解说了两种编程模式Model 1和Model2.以下是对这两种模式的简单理解.以及因为Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对照学习一下. ...

  2. Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发WebFlux 支持两种编程风(姿)格(势) 使用@Controller这种基于注解

    概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 R ...

  3. Edit Distance问题在两种编程范式下的求解

    本文已授权 [Coding博客](https://blog.coding.net) 转载 前言 Edit Distance,中文叫做编辑距离,在文本处理等领域是一个重要的问题,以下是摘自于百度百科的定 ...

  4. [python]两种编程思维--面向过程和面向对象

    例如:eg:炒一份西红柿鸡蛋 一.面向过程 面向过程的编程思维,如下 二.面向对象 制作一台炒菜机器人,然后告诉机器人做一道西红柿炒鸡蛋.在这里,我们直接面对的是机器人,而非炒菜的过程,所以这里机器人 ...

  5. EF三种编程方式的区别Database first ,Model first ,code first

    首先对于EF中先出现的datebase  first和model first两种编程方式,其的区别根据字面意思很容易能够理解. datebase  first就是代表数据库优先,那么前提就是先创建数据 ...

  6. angular2系列教程(六)两种pipe:函数式编程与面向对象编程

    今天,我们要讲的是angualr2的pipe这个知识点. 例子

  7. Arduino下LCD1602综合探究(上)——1602的两种驱动方式,如何使LCD的控制编程变得更简单

    一.前言: LCD ( Liquid Crystal Display 的简称)液晶显示器,已经逐渐替代CRT成为主流的显示设备之一,因此也成为了单片机发烧友绕不过的话题之一:而LCD1602更是很多单 ...

  8. Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

    Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...

  9. [转] LBYL与EAFP两种防御性编程风格

    检查数据可以让程序更健壮,用术语来说就是防御性编程.检查数据的时候,有这样的两种不同的风格.LBYL:Look Before You Leap  EAFP:Easier to Ask Forgiven ...

随机推荐

  1. mysql 案例~ 主从复制转化为级联复制

    一 需求 mysql 主从复制切换成级联复制二 核心思想 1 开启级联复制 2 确定postion点场景 A->B A-C 三 切换步骤  1 先确定好B为级联复制库  2 B添加log_upd ...

  2. HTTP协议-响应报文格式

    HTTP协议-响应码 浏览器向服务器发出请求,服务器处理可能是成功.可能是失败.可能没有权限访问等原因,服务器会通过响应码来告诉浏览器处理结果. " : OK " : Found ...

  3. MAC上mongodb连接不上

    1.在Mac客户端里输入 mongo,发现mongo连接不上了,原因是mongo的服务没有开启. 2.在命令行了输入 mongod,开启服务的命令 3.启动起来以后,用mongo连接服务器.

  4. kafka系列八、kafka消息重复和丢失的场景及解决方案分析

    消息重复和丢失是kafka中很常见的问题,主要发生在以下三个阶段: 生产者阶段 broke阶段 消费者阶段 一.生产者阶段重复场景 1.根本原因 生产发送的消息没有收到正确的broke响应,导致pro ...

  5. crontab定时作业

    crontab用于在指定时间执行某项作业,如执行脚本或命令. 1.crontab -e      创建一个crontab文件,并添加作业(这个crontab的拥有者是创建者). 这里要注意:必须指定s ...

  6. jumperserver3.0的安装部署

    适用于jumperserver版本:v0.3.1-2  官网:http://www.jumpserver.org/ 系统:centos7.2 基本安装 备注:如果是centos系统最好使用基本安装,否 ...

  7. echarts地图显示不正常问题

    echarts2内置地图,而echarts3无内置地图,需要自己下载并导入. 在刚开始接触地图的时候,使用dreamweaver来构建页面,使用的编码不是UTF-8 代码是按照官方的拷贝下来的(我使用 ...

  8. 关于Java源文件中public类的问题

    结论: 一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必须与之一致,否则无法编译: 如果源文件中没有一个public类,则文件名与类中没有一致性要求: 至于mai ...

  9. mysql查询不区分大小写问题分析和解决

    mysql查询默认是不区分大小写的 如: select * from some_table where str=‘abc'; select * from some_table where str='A ...

  10. pyhon----模块

    sys模块: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 s ...