1 #ifndef CAFFE2_OPERATORS_UTILS_BOXES_H_ 2 #define CAFFE2_OPERATORS_UTILS_BOXES_H_ 4 #include "caffe2/utils/eigen_utils.h" 5 #include "caffe2/utils/math.h" 15 const float BBOX_XFORM_CLIP_DEFAULT = log(1000.0 / 16.0);
35 template <
class Derived1,
class Derived2>
36 EArrXXt<typename Derived1::Scalar> bbox_transform(
37 const Eigen::ArrayBase<Derived1>& boxes,
38 const Eigen::ArrayBase<Derived2>& deltas,
39 const std::vector<typename Derived2::Scalar>& weights =
40 std::vector<typename Derived2::Scalar>{1.0, 1.0, 1.0, 1.0},
41 const float bbox_xform_clip = BBOX_XFORM_CLIP_DEFAULT,
42 const bool correct_transform_coords =
false) {
43 using T =
typename Derived1::Scalar;
44 using EArrXX = EArrXXt<T>;
45 using EArrX = EArrXt<T>;
47 if (boxes.rows() == 0) {
48 return EArrXX::Zero(T(0), deltas.cols());
51 CAFFE_ENFORCE_EQ(boxes.rows(), deltas.rows());
52 CAFFE_ENFORCE_EQ(boxes.cols(), 4);
53 CAFFE_ENFORCE_EQ(deltas.cols(), 4);
55 EArrX widths = boxes.col(2) - boxes.col(0) + T(1.0);
56 EArrX heights = boxes.col(3) - boxes.col(1) + T(1.0);
57 auto ctr_x = boxes.col(0) + T(0.5) * widths;
58 auto ctr_y = boxes.col(1) + T(0.5) * heights;
60 auto dx = deltas.col(0).template cast<T>() / weights[0];
61 auto dy = deltas.col(1).template cast<T>() / weights[1];
63 (deltas.col(2).template cast<T>() / weights[2]).cwiseMin(bbox_xform_clip);
65 (deltas.col(3).template cast<T>() / weights[3]).cwiseMin(bbox_xform_clip);
67 EArrX pred_ctr_x = dx * widths + ctr_x;
68 EArrX pred_ctr_y = dy * heights + ctr_y;
69 EArrX pred_w = dw.exp() * widths;
70 EArrX pred_h = dh.exp() * heights;
72 T offset(correct_transform_coords ? 1.0 : 0.0);
74 EArrXX pred_boxes = EArrXX::Zero(deltas.rows(), deltas.cols());
76 pred_boxes.col(0) = pred_ctr_x - T(0.5) * pred_w;
78 pred_boxes.col(1) = pred_ctr_y - T(0.5) * pred_h;
80 pred_boxes.col(2) = pred_ctr_x + T(0.5) * pred_w - offset;
82 pred_boxes.col(3) = pred_ctr_y + T(0.5) * pred_h - offset;
89 template <
class Derived>
90 EArrXXt<typename Derived::Scalar>
91 clip_boxes(
const Eigen::ArrayBase<Derived>& boxes,
int height,
int width) {
92 CAFFE_ENFORCE_EQ(boxes.cols(), 4);
94 EArrXXt<typename Derived::Scalar> ret(boxes.rows(), boxes.cols());
97 ret.col(0) = boxes.col(0).cwiseMin(width - 1).cwiseMax(0);
99 ret.col(1) = boxes.col(1).cwiseMin(height - 1).cwiseMax(0);
101 ret.col(2) = boxes.col(2).cwiseMin(width - 1).cwiseMax(0);
103 ret.col(3) = boxes.col(3).cwiseMin(height - 1).cwiseMax(0);
112 template <
class Derived>
113 std::vector<int> filter_boxes(
114 const Eigen::ArrayBase<Derived>& boxes,
116 const Eigen::Array3f& im_info) {
117 CAFFE_ENFORCE_EQ(boxes.cols(), 4);
120 min_size *= im_info[2];
122 using T =
typename Derived::Scalar;
123 using EArrX = EArrXt<T>;
125 EArrX ws = boxes.col(2) - boxes.col(0) + T(1);
126 EArrX hs = boxes.col(3) - boxes.col(1) + T(1);
127 EArrX x_ctr = boxes.col(0) + ws / T(2);
128 EArrX y_ctr = boxes.col(1) + hs / T(2);
130 EArrXb keep = (ws >= min_size) && (hs >= min_size) &&
131 (x_ctr < T(im_info[1])) && (y_ctr < T(im_info[0]));
133 return GetArrayIndices(keep);
139 #endif // CAFFE2_OPERATORS_UTILS_BOXES_H_ A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...