1 #include "integral_image_op.h" 2 #include "caffe2/utils/eigen_utils.h" 8 using EigenMatrixMapRowMajor = Eigen::Map<
9 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>;
12 using ConstEigenMatrixMapRowMajor = Eigen::Map<
13 const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>;
17 bool IntegralImageOp<float, CPUContext>::RunOnDevice() {
18 const auto& X = Input(0);
20 CAFFE_ENFORCE_EQ(X.dim(), 4,
"Only supports 4D tensors for the momement");
22 vector<int64_t> out_shape(X.sizes().vec());
25 auto* Y = Output(0, out_shape, at::dtype<float>());
26 const int ind = X.dim32(0);
27 const int chans = X.dim32(1);
28 const int rows_in = X.dim32(2);
29 const int cols_in = X.dim32(3);
30 const int rows_out = Y->dim32(2);
31 const int cols_out = Y->dim32(3);
33 const float* input_data = X.template data<float>();
34 float* output_data = Y->template mutable_data<float>();
36 const int row_out_pass_size = ind * chans * rows_out;
37 const int row_in_pass_size = ind * chans * rows_in;
38 EigenMatrixMapRowMajor<float> Y_arr(output_data, row_out_pass_size, cols_out);
39 ConstEigenMatrixMapRowMajor<float> X_arr(
40 input_data, row_in_pass_size, cols_in);
43 for (
int i = 0; i < row_out_pass_size; i++) {
44 int row = i % rows_out;
45 int diff = i / rows_out + 1;
48 for (
int j = 1; j < cols_out; ++j) {
52 for (
int j = 1; j < cols_out; ++j) {
53 Y_arr(i, j) = Y_arr(i, j - 1) + X_arr(i - diff, j - 1);
59 const int col_out_pass_size = X.dim32(0) * chans * cols_out;
60 for (
int i = 0; i < col_out_pass_size; i++) {
61 int col = i % cols_out;
62 int row = i / cols_out;
63 for (
int j = row * rows_out + 1; j < (row + 1) * rows_out; ++j) {
64 Y_arr(j, col) += Y_arr(j - 1, col);
71 bool IntegralImageGradientOp<float, CPUContext>::RunOnDevice() {
76 0, X.sizes(), at::dtype<float>());
79 const int ind = X.dim32(0);
80 const int chans = X.dim32(1);
81 const int rows_in = dY.dim32(2);
82 const int cols_in = dY.dim32(3);
83 const int rows_out = dX->dim32(2);
84 const int cols_out = dX->dim32(3);
86 const float* input_data = dY.template data<float>();
87 float* output_data = dX->template mutable_data<float>();
89 const int row_out_pass_size = ind * chans * rows_out;
90 const int row_in_pass_size = ind * chans * rows_in;
91 EigenMatrixMapRowMajor<float> dX_arr(
92 output_data, row_out_pass_size, cols_out);
93 ConstEigenMatrixMapRowMajor<float> dY_arr(
94 input_data, row_in_pass_size, cols_in);
95 Eigen::MatrixXf tmp(row_in_pass_size, cols_out);
98 for (
int i = 0; i < row_in_pass_size; i++) {
99 tmp(i, 0) = dY_arr(i, 0);
100 for (
int j = 1; j < cols_out; ++j) {
101 tmp(i, j) = tmp(i, j - 1) + dY_arr(i, j);
106 const int col_out_pass_size = X.dim32(0) * chans * cols_out;
107 for (
int i = 0; i < col_out_pass_size; i++) {
108 int col = i % cols_out;
109 int row_out_start = (i / cols_out) * rows_out;
110 int row_in_start = (i / cols_out) * rows_in;
111 dX_arr(row_out_start, col) = tmp(row_in_start, col);
112 for (
int j = 1; j < rows_out; ++j) {
113 dX_arr(row_out_start + j, col) =
114 dX_arr(row_out_start + j - 1, col) + tmp(row_in_start + j, col);
120 REGISTER_CPU_OPERATOR(IntegralImage, IntegralImageOp<float, CPUContext>);
121 REGISTER_CPU_OPERATOR(
122 IntegralImageGradient,
123 IntegralImageGradientOp<float, CPUContext>);
126 OPERATOR_SCHEMA(IntegralImage)
130 Computes an integral image, which contains the sum of pixel values within 131 an image vertically and horizontally. This integral image can then be used 132 with other detection and tracking techniques. 134 .Input(0, "X",
"Images tensor of the form (N, C, H, W)")
135 .Output(0,
"Y",
"Integrated image of the form (N, C, H+1, W+1)");
138 OPERATOR_SCHEMA(IntegralImageGradient).NumInputs(2).NumOutputs(1);
141 using GradientMakerBase::GradientMakerBase;
142 vector<OperatorDef> GetGradientDefs()
override {
144 "IntegralImageGradient",
146 vector<string>{I(0), GO(0)},
147 vector<string>{GI(0)});
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
static vector< OperatorDef > SingleGradientDef(const Args &...args)
a helper function to allow one to create one single operator def, which is usually the case for many ...