1+ #include " cupoch/geometry/image.h"
2+
3+ using namespace cupoch ;
4+ using namespace cupoch ::geometry;
5+
6+ namespace {
7+
8+ struct vertical_flip_functor {
9+ vertical_flip_functor (const uint8_t * src, int width, int height,
10+ int bytes_per_pixel, uint8_t * dst)
11+ : src_(src), width_(width), height_(height), bytes_per_pixel_(bytes_per_pixel), dst_(dst) {};
12+ const uint8_t * src_;
13+ const int width_;
14+ const int height_;
15+ const int bytes_per_pixel_;
16+ uint8_t * dst_;
17+ __device__
18+ void operator () (size_t idx) {
19+ const int y = idx / width_;
20+ const int x = idx % width_;
21+ memcpy (&dst_[(height_ - y - 1 ) * width_ * bytes_per_pixel_ + x], &src_[idx], bytes_per_pixel_ * sizeof (uint8_t ));
22+ }
23+ };
24+
25+ struct horizontal_flip_functor {
26+ horizontal_flip_functor (const uint8_t * src, int width, int height,
27+ int bytes_per_pixel, uint8_t * dst)
28+ : src_(src), width_(width), height_(height), bytes_per_pixel_(bytes_per_pixel), dst_(dst) {};
29+ const uint8_t * src_;
30+ const int width_;
31+ const int height_;
32+ const int bytes_per_pixel_;
33+ uint8_t * dst_;
34+ __device__
35+ void operator () (size_t idx) {
36+ const int y = idx / width_;
37+ const int x = idx % width_;
38+ memcpy (&dst_[y * width_ * bytes_per_pixel_ + (width_ - x - 1 )], &src_[idx], bytes_per_pixel_ * sizeof (uint8_t ));
39+ }
40+ };
41+
42+ }
43+
44+
45+ Image::Image () : Geometry2D(Geometry::GeometryType::Image) {}
46+ Image::~Image () {}
47+
48+ Image &Image::Clear () {
49+ width_ = 0 ;
50+ height_ = 0 ;
51+ num_of_channels_ = 0 ;
52+ bytes_per_channel_ = 0 ;
53+ data_.clear ();
54+ return *this ;
55+ }
56+
57+ bool Image::IsEmpty () const {
58+ return !HasData ();
59+ }
60+
61+ Eigen::Vector2f Image::GetMinBound () const {
62+ return Eigen::Vector2f (0.0 , 0.0 );
63+ }
64+
65+ Eigen::Vector2f Image::GetMaxBound () const {
66+ return Eigen::Vector2f (width_, height_);
67+ }
68+
69+ thrust::host_vector<uint8_t > Image::GetData () const {
70+ thrust::host_vector<uint8_t > data = data_;
71+ return data;
72+ }
73+
74+ void Image::SetData (const thrust::host_vector<uint8_t >& data) {
75+ data_ = data;
76+ }
77+
78+ bool Image::TestImageBoundary (float u,
79+ float v,
80+ float inner_margin /* = 0.0 */ ) const {
81+ return (u >= inner_margin && u < width_ - inner_margin &&
82+ v >= inner_margin && v < height_ - inner_margin);
83+ }
84+
85+ std::shared_ptr<Image> Image::FlipVertical () const {
86+ auto output = std::make_shared<Image>();
87+ output->Prepare (width_, height_, num_of_channels_, bytes_per_channel_);
88+
89+ vertical_flip_functor func (thrust::raw_pointer_cast (data_.data ()), width_, height_,
90+ num_of_channels_ * bytes_per_channel_,
91+ thrust::raw_pointer_cast (output->data_ .data ()));
92+ thrust::for_each (thrust::make_counting_iterator<size_t >(0 ), thrust::make_counting_iterator (data_.size ()), func);
93+ return output;
94+ }
95+
96+ std::shared_ptr<Image> Image::FlipHorizontal () const {
97+ auto output = std::make_shared<Image>();
98+ output->Prepare (width_, height_, num_of_channels_, bytes_per_channel_);
99+
100+ horizontal_flip_functor func (thrust::raw_pointer_cast (data_.data ()), width_, height_,
101+ num_of_channels_ * bytes_per_channel_,
102+ thrust::raw_pointer_cast (output->data_ .data ()));
103+ thrust::for_each (thrust::make_counting_iterator<size_t >(0 ), thrust::make_counting_iterator (data_.size ()), func);
104+ return output;
105+ }
106+
107+ void Image::AllocateDataBuffer () {
108+ data_.resize (width_ * height_ * num_of_channels_ * bytes_per_channel_);
109+ }
0 commit comments