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;
}