从 Fast R-CNN 的所有边界框提取特征
extracting features from all bounding boxes of Fast R-CNN
我刚刚安装了 Fast RCNN 并且有 运行 演示,
我想知道是否可以从图像中的所有边界框提取特征(并对整个数据集执行此操作)。
例如,如果 Fast RCNN 从图像中检测到猫、狗和汽车,
我想为猫、狗和汽车提取单独的 CNN 特征。
并对数以万计的图像执行此操作。
Fast RCNN 的 Github (https://github.com/rbgirshick/caffe-fast-rcnn/tree/master/examples/feature_extraction) 上的特征提取示例似乎是使用 caffe 对整个图像进行特征提取的复制品,而不是每个边界框。
谁能帮我解决这个问题?
更新:
显然,每个边界框的特征提取是在 https://github.com/rbgirshick/fast-rcnn/blob/master/lib/fast_rcnn/test.py 的以下代码部分中完成的:
# When mapping from image ROIs to feature map ROIs, there's some aliasing
# (some distinct image ROIs get mapped to the same feature ROI).
# Here, we identify duplicate feature ROIs, so we only compute features
# on the unique subset.
if cfg.DEDUP_BOXES > 0:
v = np.array([1, 1e3, 1e6, 1e9, 1e12])
hashes = np.round(blobs['rois'] * cfg.DEDUP_BOXES).dot(v)
_, index, inv_index = np.unique(hashes, return_index=True,
return_inverse=True)
blobs['rois'] = blobs['rois'][index, :]
boxes = boxes[index, :]
# reshape network inputs
net.blobs['data'].reshape(*(blobs['data'].shape))
net.blobs['rois'].reshape(*(blobs['rois'].shape))
blobs_out = net.forward(data=blobs['data'].astype(np.float32, copy=False),
rois=blobs['rois'].astype(np.float32, copy=False))
if cfg.TEST.SVM:
# use the raw scores before softmax under the assumption they
# were trained as linear SVMs
scores = net.blobs['cls_score'].data
else:
# use softmax estimated probabilities
scores = blobs_out['cls_prob']
if cfg.TEST.BBOX_REG:
# Apply bounding-box regression deltas
box_deltas = blobs_out['bbox_pred']
pred_boxes = _bbox_pred(boxes, box_deltas)
pred_boxes = _clip_boxes(pred_boxes, im.shape)
else:
# Simply repeat the boxes, once for each class
pred_boxes = np.tile(boxes, (1, scores.shape[1]))
if cfg.DEDUP_BOXES > 0:
# Map scores and predictions back to the original set of boxes
scores = scores[inv_index, :]
pred_boxes = pred_boxes[inv_index, :]
return scores, pred_boxes
我正在尝试弄清楚如何调整它以保存特征,就像我们对整个图像的特征使用 Caffe 所做的那样,这些图像被保存到 mdb 文件中。
更新
在确定正确边界框的过程中,Fast-RCNN 从大量 (~800-2000) 个图像区域中提取 CNN 特征,称为 object proposals。这些区域是通过不同的算法获得的,通常是selective search。计算完成后,它使用这些特征来识别 "right" 提案并找出 "right" 边界框。这称为边界框回归。
当然Fast-RCNN优化了这个过程,但是仍然需要从比感兴趣对象相关的区域更多的区域中提取CNN特征特征。
很快,如果您要在粘贴的代码快照中保存变量 blobs_out
,您将保存与 所有 对象提案相关的功能,包括"wrong" 个提案。但是您可以保存所有这些,然后尝试修剪并仅检索所需的。要保存功能,只需使用 pickle.dump()
.
查看 test_net
函数的结尾,here。 nms_dets
变量似乎存储了最终的框。可能有一种方法可以提取您存储的 blobs_out
并删除不需要的功能,但它似乎并不那么简单。
我能想到的最简单的解决方案如下。
让我们用 Fast-RCNN 计算最终的边界框。然后,提取相关图像块,如下所示(我假设 Python):
img = cv2.imread('/path/to/image')
for bbox in bboxes_list:
x0, y0, x1, y1 = bbox
cut = img[y0:y1, x0:x1]
extract_cnn_features(cut)
特征提取与整个图像情况相同:
net = Caffe.NET('deploy.prototxt', 'caffemodel', caffe.TEST)
# preprocess input
net.blobs['data'].data[...] = net_input
net.forward()
feats = net.blobs['my_layer'].data.copy()
当然,这种方法的计算量很大,因为您基本上是计算两倍 CNN 特征。这取决于您对速度和 CNN 模型大小的要求。
我刚刚安装了 Fast RCNN 并且有 运行 演示,
我想知道是否可以从图像中的所有边界框提取特征(并对整个数据集执行此操作)。
例如,如果 Fast RCNN 从图像中检测到猫、狗和汽车,
我想为猫、狗和汽车提取单独的 CNN 特征。
并对数以万计的图像执行此操作。
Fast RCNN 的 Github (https://github.com/rbgirshick/caffe-fast-rcnn/tree/master/examples/feature_extraction) 上的特征提取示例似乎是使用 caffe 对整个图像进行特征提取的复制品,而不是每个边界框。
谁能帮我解决这个问题?
更新:
显然,每个边界框的特征提取是在 https://github.com/rbgirshick/fast-rcnn/blob/master/lib/fast_rcnn/test.py 的以下代码部分中完成的:
# When mapping from image ROIs to feature map ROIs, there's some aliasing
# (some distinct image ROIs get mapped to the same feature ROI).
# Here, we identify duplicate feature ROIs, so we only compute features
# on the unique subset.
if cfg.DEDUP_BOXES > 0:
v = np.array([1, 1e3, 1e6, 1e9, 1e12])
hashes = np.round(blobs['rois'] * cfg.DEDUP_BOXES).dot(v)
_, index, inv_index = np.unique(hashes, return_index=True,
return_inverse=True)
blobs['rois'] = blobs['rois'][index, :]
boxes = boxes[index, :]
# reshape network inputs
net.blobs['data'].reshape(*(blobs['data'].shape))
net.blobs['rois'].reshape(*(blobs['rois'].shape))
blobs_out = net.forward(data=blobs['data'].astype(np.float32, copy=False),
rois=blobs['rois'].astype(np.float32, copy=False))
if cfg.TEST.SVM:
# use the raw scores before softmax under the assumption they
# were trained as linear SVMs
scores = net.blobs['cls_score'].data
else:
# use softmax estimated probabilities
scores = blobs_out['cls_prob']
if cfg.TEST.BBOX_REG:
# Apply bounding-box regression deltas
box_deltas = blobs_out['bbox_pred']
pred_boxes = _bbox_pred(boxes, box_deltas)
pred_boxes = _clip_boxes(pred_boxes, im.shape)
else:
# Simply repeat the boxes, once for each class
pred_boxes = np.tile(boxes, (1, scores.shape[1]))
if cfg.DEDUP_BOXES > 0:
# Map scores and predictions back to the original set of boxes
scores = scores[inv_index, :]
pred_boxes = pred_boxes[inv_index, :]
return scores, pred_boxes
我正在尝试弄清楚如何调整它以保存特征,就像我们对整个图像的特征使用 Caffe 所做的那样,这些图像被保存到 mdb 文件中。
更新
在确定正确边界框的过程中,Fast-RCNN 从大量 (~800-2000) 个图像区域中提取 CNN 特征,称为 object proposals。这些区域是通过不同的算法获得的,通常是selective search。计算完成后,它使用这些特征来识别 "right" 提案并找出 "right" 边界框。这称为边界框回归。
当然Fast-RCNN优化了这个过程,但是仍然需要从比感兴趣对象相关的区域更多的区域中提取CNN特征特征。
很快,如果您要在粘贴的代码快照中保存变量 blobs_out
,您将保存与 所有 对象提案相关的功能,包括"wrong" 个提案。但是您可以保存所有这些,然后尝试修剪并仅检索所需的。要保存功能,只需使用 pickle.dump()
.
查看 test_net
函数的结尾,here。 nms_dets
变量似乎存储了最终的框。可能有一种方法可以提取您存储的 blobs_out
并删除不需要的功能,但它似乎并不那么简单。
我能想到的最简单的解决方案如下。
让我们用 Fast-RCNN 计算最终的边界框。然后,提取相关图像块,如下所示(我假设 Python):
img = cv2.imread('/path/to/image')
for bbox in bboxes_list:
x0, y0, x1, y1 = bbox
cut = img[y0:y1, x0:x1]
extract_cnn_features(cut)
特征提取与整个图像情况相同:
net = Caffe.NET('deploy.prototxt', 'caffemodel', caffe.TEST)
# preprocess input
net.blobs['data'].data[...] = net_input
net.forward()
feats = net.blobs['my_layer'].data.copy()
当然,这种方法的计算量很大,因为您基本上是计算两倍 CNN 特征。这取决于您对速度和 CNN 模型大小的要求。