#ifndef CAFFE_CROP_LAYER_HPP_ #define CAFFE_CROP_LAYER_HPP_ #include #include #include "caffe/blob.hpp" #include "caffe/layer.hpp" #include "caffe/proto/caffe.pb.h" namespace caffe { /** * @brief Takes a Blob and crop it, to the shape specified by the second input * Blob, across all dimensions after the specified axis. * * TODO(dox): thorough documentation for Forward, Backward, and proto params. */ template class CropLayer : public Layer { public: explicit CropLayer(const LayerParameter& param) : Layer(param) {} virtual void LayerSetUp(const vector*>& bottom, const vector*>& top); virtual void Reshape(const vector*>& bottom, const vector*>& top); virtual inline const char* type() const { return "Crop"; } virtual inline int ExactNumBottomBlobs() const { return 2; } virtual inline int ExactNumTopBlobs() const { return 1; } protected: virtual void Forward_cpu(const vector*>& bottom, const vector*>& top); virtual void Backward_cpu(const vector*>& top, const vector& propagate_down, const vector*>& bottom); virtual void Forward_gpu(const vector*>& bottom, const vector*>& top); virtual void Backward_gpu(const vector*>& top, const vector& propagate_down, const vector*>& bottom); Blob offsets; Blob src_strides_; Blob dest_strides_; private: // Recursive copy function. void crop_copy(const vector*>& bottom, const vector*>& top, const int* offsets, vector indices, int cur_dim, const Dtype* src_data, Dtype* dest_data, bool is_forward); // Recursive copy function: this is similar to crop_copy() but loops over all // but the last two dimensions to allow for ND cropping while still relying on // a CUDA kernel for the innermost two dimensions for performance reasons. An // alterantive implementation could rely on the kernel more by passing // offsets, but this is problematic because of its variable length. // Since in the standard (N,C,W,H) case N,C are usually not cropped a speedup // could be achieved by not looping the application of the copy_kernel around // these dimensions. void crop_copy_gpu(const vector*>& bottom, const vector*>& top, const vector& offsets, vector indices, int cur_dim, const Dtype* src_data, Dtype* dest_data, bool is_forward); }; } // namespace caffe #endif // CAFFE_CROP_LAYER_HPP_