Tensor crop()

in src/io/image_transformer.cc [201:271]


Tensor crop(Tensor& input, const size_t crop_height, const size_t crop_width,
            const size_t crop_h_offset, const size_t crop_w_offset,
            const string& image_dim_order) {
  CHECK_LE(input.nDim(), 4u);
  CHECK_GE(input.nDim(), 2u);

  Tensor output;
  const float* in = input.data<float>();
  size_t out_idx = 0, in_idx = 0;
  if (input.nDim() == 4u) {
    /// TODO
    LOG(FATAL) << "Not implemented";
  } else if (input.nDim() == 3u) {
    if (image_dim_order == "CHW") {
      size_t height = input.shape(1), width = input.shape(2),
             channel = input.shape(0);
      CHECK_LE(crop_height + crop_h_offset, height);
      CHECK_LE(crop_width + crop_w_offset, width);
      float* out = new float[crop_height * crop_width * channel];
      for (size_t c = 0; c < channel; c++) {
        for (size_t h = 0; h < crop_height; h++) {
          for (size_t w = 0; w < crop_width; w++) {
            in_idx = (c * height + crop_h_offset + h) * width + crop_w_offset + w;
            out_idx = (c * crop_height + h) * crop_width + w;
            out[out_idx] = in[in_idx];
          }
        }
      }
      output.Resize(Shape{channel, crop_height, crop_width});
      output.CopyDataFromHostPtr<float>(out, crop_height * crop_width * channel);
      delete[] out;
    } else if (image_dim_order == "HWC") {
      size_t height = input.shape(0), width = input.shape(1),
             channel = input.shape(2);
      CHECK_LE(crop_height + crop_h_offset, height);
      CHECK_LE(crop_width + crop_w_offset, width);
      float* out = new float[crop_height * crop_width * channel];
      for (size_t c = 0; c < channel; c++) {
        for (size_t h = 0; h < crop_height; h++) {
          for (size_t w = 0; w < crop_width; w++) {
            in_idx = ((crop_h_offset + h) * width + crop_w_offset + w) * channel + c;
            out_idx = (h * crop_width + w) * channel + c;
            out[out_idx] = in[in_idx];
          }
        }
      }
      output.Resize(Shape{crop_height, crop_width, channel});
      output.CopyDataFromHostPtr<float>(out, crop_height * crop_width * channel);
      delete[] out;
    } else {
      LOG(FATAL) << "Unknow dimension order for images " << image_dim_order
                 << " Only support 'HWC' and 'CHW'";
    }
  } else { /// 2D gray image
    size_t height = input.shape(0), width = input.shape(1);
    CHECK_LE(crop_height + crop_h_offset, height);
    CHECK_LE(crop_width + crop_w_offset, width);
    float* out = new float[crop_height * crop_width];
    for (size_t h = 0; h < crop_height; h++) {
      for (size_t w = 0; w < crop_width; w++) {
        in_idx = (crop_h_offset + h) * width + crop_w_offset + w;
        out_idx = h * crop_width + w;
        out[out_idx] = in[in_idx];
      }
    }
    output.Resize(Shape{crop_height, crop_width});
    output.CopyDataFromHostPtr<float>(out, crop_height * crop_width);
    delete[] out;
  }
  return output;
}