java classifier_Faster RCNN 推理 从头写 java (五) Classifier网络输出对 ROIs过滤与修正...

该博客介绍了深度学习中目标检测的一个关键步骤,涉及ROI池化和候选框的过滤与修正。首先,从RPN输出的ROIs和Classifier网络的输出P_cls、P_regr中筛选出非背景且概率大于0.8的候选框。接着,使用Classifier的回归输出修正ROI坐标,然后将修正后的坐标转换到VGG16特征图维度,并准备进行NMS处理。整个流程详述了目标检测中候选框的选择和优化过程。
摘要由CSDN通过智能技术生成

目录:

一: 输入输出

输入:

ROIs: RPN to ROI 流程的输出, shape 为 [300, 4]

P_cls: Classifier网络的输出, shape为 [1, 32, 2]

P_regr: Classifier网络的输出, shape为 [1, 32, 4]

输出:

candidate_bboxes: 备选的boxes, shape为 [N, 4] N 表示未知

candidate_probs: 备选的boxes的概率, shape为 [N, ] N 表示未知

二: 流程

过滤掉背景和概率小于0.8的bbox

使用P_regr修正ROI

三: code by code

将classifier 网络的输出P_cls, P_regr 转换为Nd4j INDArray

INDArray P_cls = TypeConvertor.tensorToNDArray_s3(classifier_output.getCls());

INDArray P_regr = TypeConvertor.tensorToNDArray_s3(classifier_output.getRegression());

遍历每个ROIs,并切过滤掉背景和概率小于0.8 的ROI

for (int ii = 0; ii < P_cls.shape()[1]; ii++)

{

INDArray theCls = P_cls.get(NDArrayIndex.point(0), NDArrayIndex.point(ii), NDArrayIndex.all());

// 是否背景.

boolean isBackground = theCls.argMax(0).getInt(0) == (P_cls.shape()[2] - 1);

// 小于0.8概率 || 是背景

if (theCls.maxNumber().floatValue() < bbox_threshold || isBackground)

{

continue;

}

提取对应的ROI坐标和回归值

int x = ROIs.getInt(0, ii, 0);

int y = ROIs.getInt(0, ii, 1);

int w = ROIs.getInt(0, ii, 2);

int h = ROIs.getInt(0, ii, 3);

float tx = P_regr.getFloat(new int[]{0, ii, 0});

float ty = P_regr.getFloat(new int[]{0, ii, 1});

float tw = P_regr.getFloat(new int[]{0, ii, 2});

float th = P_regr.getFloat(new int[]{0, ii, 3});

使用Classifier的输出P_regr 来修正ROI, 这个算法逻辑与训练时生成Classifier 网络标注算法相反.

tx /= classifier_regr_std[0];

ty /= classifier_regr_std[1];

tw /= classifier_regr_std[2];

th /= classifier_regr_std[3];

int[] coor_out;

try {

// [x, y, w, h] 格式.

// coor_out[0]: x

// coor_out[1]: y

// coor_out[2]: w

// coor_out[3]: h

coor_out = apply_regr(x, y, w, h, tx, ty, tw, th);

}

catch (Exception e)

{

continue;

}

将修正后的ROI坐标转换到VGG16的feature map 维度上,rpn_stride = 16

并将坐标从 [x1, y1, x2, y2] 转为 [x, y, w, h]

float x1 = coor_out[0] * rpn_stride;

float y1 = coor_out[1] * rpn_stride;

float x2 = (coor_out[0] + coor_out[2]) * rpn_stride;

float y2 = (coor_out[1] + coor_out[3]) * rpn_stride;

float[] bbox = new float[] {

coor_out[0] * rpn_stride,

coor_out[1] * rpn_stride,

(coor_out[0] + coor_out[2]) * rpn_stride,

(coor_out[1] + coor_out[3]) * rpn_stride

};

纵向排列一下,将N个bboxes的数组构建成INDArray shape = [N, 4]

修正为NMS(非最大值抑制)的数据输入格式. 下一个流程就需要执行NMS了。

INDArray candidate_bboxes = Nd4j.vstack(bboxes);

INDArray candidate_probs = Nd4j.create(probs);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值