环境准备
pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple
图片读取&画框
from skimage import io
import matplotlib.pyplot as plt
import matplotlib.patches as mp
ss = io.imread('dogs.jpg')
_, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(ss)
rect = mp.Rectangle((600, 400), 100, 80, fill=False, edgecolor='red', linewidth=1)
ax.add_patch(rect)
plt.show()
运行代码,显示如下
Selective Search
方法特点
- 捕捉不同尺度(Capture All Scales)
- 多样化(Diversification)
- 快速计算(Fast to Compute)
图像中区域特征比像素更具代表性
- 计算所有邻近区域之间的相似性;
- 两个最相似的区域被组合在一起;
- 计算合并区域和相邻区域的相似度;
- 重复2、3过程,直到整个图像变为一个区域
另外加入一些多样性的衡量
- 颜色相似性
- 纹理相似性
- 尺度相似性
- 形状重合度
效果如下
Selective Search环境准备
pip install selectivesearch
生成示例图片的框
from skimage import io
import selectivesearch
ss = io.imread('dogs.jpg')
# ss生成目标框
_, regions = selectivesearch.selective_search(ss, scale=500, sigma=0.9, min_size=10)
print(len(regions))
for i in regions[0:5]:
print(i)
运行代码,打印信息如下
2437
{'rect': (0, 0, 1299, 951), 'size': 47450, 'labels': [0.0]}
{'rect': (48, 0, 96, 0), 'size': 97, 'labels': [1.0]}
{'rect': (432, 0, 319, 0), 'size': 320, 'labels': [2.0]}
{'rect': (1120, 0, 47, 1), 'size': 64, 'labels': [3.0]}
{'rect': (0, 7, 340, 0), 'size': 341, 'labels': [4.0]}
对候选框进行过滤
- 去除重复框
- 删除小框
- 删除宽高比较大的框
代码如下
candidates = set()
for r in regions:
# with different segments
if r['rect'] in candidates:
continue
# 删除 < 2000 pixels
if r['size'] < 2000:
continue
# 删除 宽高比 > 1.2
x, y, w, h = r['rect']
if w / h > 1.2 or h / w > 1.2:
continue
candidates.add(r['rect'])
print(candidates)
运行代码,打印如下
{(857, 523, 429, 375), (864, 520, 426, 431), (207, 266, 139, 143), (508, 523, 330, 373), (1058, 344, 75, 65), (75, 522, 405, 375), (854, 520, 434, 378), (1060, 344, 73, 64), (23, 32, 233, 268), (75, 522, 406, 375), (176, 600, 307, 298), (1059, 11, 141, 165), (0, 133, 258, 275), (493, 523, 346, 376), (1105, 285, 141, 124), (1102, 280, 144, 129), (855, 521, 431, 377), (776, 8, 519, 503), (396, 122, 279, 285), (1059, 344, 74, 64), (1101, 236, 137, 129), (508, 523, 330, 376), (137, 551, 347, 347), (508, 523, 331, 376), (65, 521, 419, 377), (589, 228, 172, 181), (1057, 11, 93, 88), (0, 8, 349, 401), (1101, 227, 186, 182), (154, 551, 330, 347), (855, 521, 433, 377), (688, 750, 150, 148), (1129, 285, 117, 124), (1057, 9, 229, 216), (1059, 11, 142, 165), (363, 9, 399, 400), (23, 32, 323, 377), (363, 9, 398, 400), (341, 8, 423, 405), (176, 551, 308, 347), (887, 650, 186, 187), (176, 600, 308, 298), (23, 32, 324, 377)}
显示满足条件的候选框
from skimage import io
import selectivesearch
import matplotlib.pyplot as plt
import matplotlib.patches as mp
ss = io.imread('dogs.jpg')
_, regions = selectivesearch.selective_search(ss, scale=500, sigma=0.9, min_size=10)
# 过滤框
candidates = set()
index = 0
for r in regions:
index += 1
print(index)
# with different segments
if r['rect'] in candidates:
continue
# 删除 < 2000 pixels
if r['size'] < 2000:
continue
# 删除 宽高比 > 1.2
x, y, w, h = r['rect']
if w / h > 1.2 or h / w > 1.2:
continue
candidates.add(r['rect'])
# 画图
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(ss)
for x, y, w, h in candidates:
rect = mp.Rectangle((x, y), w, h, fill=False, edgecolor='red', linewidth=1)
ax.add_patch(rect)
plt.show()
运行代码,显示如下
候选区域预处理
SelectiveSearch在一张图片上提取出来约2000个侯选区域, 需要注意的是这些候选区域的长宽不固定
如下图所示
将每个region固定到227*227
的尺寸
why ?
- CNN主要由两部分组成:卷积和全连接部分
- 卷积部分通过滑窗进行计算,并输出代表激活的空间排布的特征图(feature map),卷积并不需要固定的图像尺寸,可以产生任意尺寸的特征图
- 全连接层的输入数据维度是固定的
RCNN结构
CNN特征提取
CNN训练
使用imagenet上预训练的AlexNet,把网络的最后一个fc层的1000改为(论文测试的数据集是20类object+background)N+1(N为类别的数目,1是加一个背景)来fine-tuning用于提取特征的CNN。
正样本
- 候选区域与人工标注的真实框的IOU >=0.5
负样本
- IOU小于0.5
正负样本比例
- 每个batch_size = 128,32个是正样本,96个是负样本
学习率
- 0.001(初始学习率的1/10
梯度更新:SGD
SVM分类
正样本
- 候选框包含整个目标
负样本
- IoU < 0.3
一张图片产生2000个侯选区域,提取出来的就是2000 x 4096这样的特征向量(R-CNN当中默认CNN层输出4096特征向量)
对20类中的每一类,分别训练一个SVM分类器
候选框回归