libcvd
utility.h
1 #ifndef CVD_UTILITY_H
2 #define CVD_UTILITY_H
3 
4 #include <cstdint>
5 
6 #include <cvd/image.h>
7 #include <cvd/internal/convert_pixel_types.h>
8 #include <cvd/internal/pixel_traits.h>
9 #include <type_traits>
10 
11 namespace CVD
12 { //begin namespace
13 
29 template <class S, class T>
30 void copy(const BasicImage<S>& in, BasicImage<T>& out, ImageRef size = ImageRef(-1, -1), ImageRef begin = ImageRef(), ImageRef dst = ImageRef())
31 {
32  if(size.x == -1 && size.y == -1)
33  size = in.size();
34  // FIXME: This should be an exception, but which one do I use?
35  // I refuse to define another "ImageRefNotInImage" in this namespace.
36  if(!(in.in_image(begin) && out.in_image(dst) && in.in_image(begin + size - ImageRef(1, 1)) && out.in_image(dst + size - ImageRef(1, 1))))
37  {
38  std::cerr << "bad copy: " << in.size() << " " << out.size() << " " << size << " " << begin << " " << dst << std::endl;
39  int* p = 0;
40  *p = 1;
41  }
42  if(in.size() == out.size() && size == in.size() && begin == ImageRef() && dst == ImageRef())
43  {
44  convert_image(in, out);
45  return;
46  }
47 
48  const S* from = &in[begin];
49  T* to = &out[dst];
50  int i = 0;
51  while(i++ < size.y)
52  {
53  Pixel::ConvertPixels<S, T>::convert(from, to, size.x);
54  from += in.size().x;
55  to += out.size().x;
56  }
57 }
58 
59 template <class T, bool pod = std::is_pod<T>::value>
60 struct ZeroPixel
61 {
62  static void zero(T& t)
63  {
64  for(unsigned int c = 0; c < Pixel::Component<T>::count; c++)
65  Pixel::Component<T>::get(t, c) = 0;
66  }
67 };
68 
69 template <class T>
70 struct ZeroPixel<T, true>
71 {
72  static void zero(T& t) { memset(&t, 0, sizeof(T)); }
73 };
74 
75 template <class T, bool pod = std::is_pod<T>::value>
76 struct ZeroPixels
77 {
78  static void zero(T* pixels, int count)
79  {
80  if(count)
81  {
82  ZeroPixel<T>::zero(*pixels);
83  std::fill(pixels + 1, pixels + count, *pixels);
84  }
85  }
86 };
87 
88 template <class T>
89 struct ZeroPixels<T, true>
90 {
91  static void zero(T* pixels, int count)
92  {
93  memset(pixels, 0, sizeof(T) * count);
94  }
95 };
96 
99 template <class T>
100 inline void zeroPixel(T& pixel) { ZeroPixel<T>::zero(pixel); }
101 
104 template <class T>
105 inline void zeroPixels(T* pixels, int count) { ZeroPixels<T>::zero(pixels, count); }
106 
108 template <class T>
110 {
111  if(I.size().y == 0)
112  return;
113  zeroPixels(I[0], I.size().x);
114  for(int r = 0; r < I.size().y - 1; r++)
115  zeroPixels(I[r] + I.size().x - 1, 2);
116  zeroPixels(I[I.size().y - 1], I.size().x);
117 }
118 
124 template <class T>
125 void fillBorders(BasicImage<T>& im, const T pix, int w = 1)
126 {
127  //Fill the top and bottom
128  for(int n = 0; n < w; n++)
129  for(int x = 0; x < im.size().x; x++)
130  {
131  im[n][x] = pix;
132  im[im.size().y - 1 - n][x] = pix;
133  }
134 
135  for(int y = w; y < im.size().y - w; y++)
136  for(int n = 0; n < w; n++)
137  {
138  im[y][n] = pix;
139  im[y][im.size().x - 1 - n] = pix;
140  }
141 }
142 
146 template <class A, class B>
147 inline void differences(const A* a, const A* b, B* diff, size_t count)
148 {
149  while(count--)
150  *(diff++) = (B) * (a++) - (B) * (b++);
151 }
152 
156 template <class A, class B, class C>
157 inline void add_multiple_of_sum(const A* a, const A* b, const C& c, B* out, size_t count)
158 {
159  while(count--)
160  *(out++) += (*(a++) + *(b++)) * c;
161 }
162 
166 template <class A, class B, class C>
167 inline void assign_multiple(const A* a, const B& c, C* out, size_t count)
168 {
169  while(count--)
170  *(out++) = static_cast<C>(*(a++) * c);
171 }
172 
176 template <class T>
177 double inner_product(const T* a, const T* b, size_t count)
178 {
179  double dot = 0;
180  while(count--)
181  dot += *(a++) * *(b++);
182  return dot;
183 }
184 
185 template <class R, class D, class T>
187 {
188  static inline R sum_squared_differences(const T* a, const T* b, size_t count)
189  {
190  R ssd = 0;
191  while(count--)
192  {
193  D d = *a++ - *b++;
194  ssd += d * d;
195  }
196  return ssd;
197  }
198 };
199 
200 template <class T1, class T2>
201 inline void square(const T1* in, T2* out, size_t count)
202 {
203  while(count--)
204  {
205  *(out++) = static_cast<T2>(*in * *in);
206  ++in;
207  }
208 }
209 
210 template <class T1, class T2>
211 inline void subtract_square(const T1* in, T2* out, size_t count)
212 {
213  while(count--)
214  {
215  *(out++) -= static_cast<T2>(*in * *in);
216  ++in;
217  }
218 }
219 
223 template <class T>
224 inline double sum_squared_differences(const T* a, const T* b, size_t count)
225 {
227 }
228 
230 template <int bytes>
231 bool is_aligned(const void* ptr);
232 template <>
233 inline bool is_aligned<8>(const void* ptr) { return ((reinterpret_cast<size_t>(ptr)) & 0x7) == 0; }
234 template <>
235 inline bool is_aligned<16>(const void* ptr) { return ((reinterpret_cast<size_t>(ptr)) & 0xF) == 0; }
236 
238 template <int A, class T>
239 inline size_t steps_to_align(const T* ptr)
240 {
241  return is_aligned<A>(ptr) ? 0 : (A - ((reinterpret_cast<size_t>(ptr)) & (A - 1))) / sizeof(T);
242 }
243 
244 void differences(const byte* a, const byte* b, short* diff, unsigned int size);
245 void differences(const short* a, const short* b, short* diff, unsigned int size);
246 
247 void differences(const float* a, const float* b, float* diff, size_t size);
248 void add_multiple_of_sum(const float* a, const float* b, const float& c, float* out, size_t count);
249 void assign_multiple(const float* a, const float& c, float* out, size_t count);
250 double inner_product(const float* a, const float* b, size_t count);
251 double sum_squared_differences(const float* a, const float* b, size_t count);
252 void square(const float* in, float* out, size_t count);
253 void subtract_square(const float* in, float* out, size_t count);
254 
255 void differences(const int32_t* a, const int32_t* b, int32_t* diff, size_t size);
256 void differences(const double* a, const double* b, double* diff, size_t size);
257 void add_multiple_of_sum(const double* a, const double* b, const double& c, double* out, size_t count);
258 void assign_multiple(const double* a, const double& c, double* out, size_t count);
259 double inner_product(const double* a, const double* b, size_t count);
260 double sum_squared_differences(const double* a, const double* b, size_t count);
261 long long sum_squared_differences(const byte* a, const byte* b, size_t count);
262 
263 }
264 
265 #endif
All classes and functions are within the CVD namespace.
Definition: argb.h:6
double sum_squared_differences(const T *a, const T *b, size_t count)
Compute sum of (a_i - b_i)^2 (the SSD) This is accelerated using SIMD for some platforms and data typ...
Definition: utility.h:224
ImageRef size() const
What is the size of this image?
Definition: image.h:557
Definition: utility.h:186
void add_multiple_of_sum(const A *a, const A *b, const C &c, B *out, size_t count)
Compute pointwise (a_i + b_i) * c and add to out_i This is accelerated using SIMD for some platforms ...
Definition: utility.h:157
Definition: utility.h:60
void fillBorders(BasicImage< T > &im, const T pix, int w=1)
Fill image borders.
Definition: utility.h:125
Definition: utility.h:76
void copy(const BasicImage< S > &in, BasicImage< T > &out, ImageRef size=ImageRef(-1, -1), ImageRef begin=ImageRef(), ImageRef dst=ImageRef())
Generic image copy function for copying sub rectangles of images into other images.
Definition: utility.h:30
size_t steps_to_align(const T *ptr)
Compute the number of pointer increments necessary to yield alignment of A bytes. ...
Definition: utility.h:239
int x
The x co-ordinate.
Definition: image_ref.h:172
double inner_product(const T *a, const T *b, size_t count)
Compute sum(a_i*b_i) This is accelerated using SIMD for some platforms and data types (alignment is c...
Definition: utility.h:177
Definition: image_ref.h:29
void zeroBorders(BasicImage< T > &I)
Set the one-pixel border (top, bottom, sides) of an image to zero values.
Definition: utility.h:109
unsigned char byte
An 8-bit datatype.
Definition: byte.h:8
A generic image class to manage a block of arbitrarily padded data as an image.
Definition: image.h:273
void convert_image(const BasicImage< bayer_bggr > &from, BasicImage< byte > &to)
Convert Bayer pattern of various forms to greyscale data.
void zeroPixel(T &pixel)
Set a pixel to the default value (typically 0) For multi-component pixels, this zeros all components ...
Definition: utility.h:100
Definition: convert_pixel_types.h:441
void assign_multiple(const A *a, const B &c, C *out, size_t count)
Compute pointwise a_i * c and store in out_i This is accelerated using SIMD for some platforms and da...
Definition: utility.h:167
Definition: builtin_components.h:38
void differences(const A *a, const A *b, B *diff, size_t count)
Compute pointwise differences (a_i - b_i) and store in diff_i This is accelerated using SIMD for some...
Definition: utility.h:147
bool is_aligned(const void *ptr)
Check if the pointer is aligned to the specified byte granularity.
void zeroPixels(T *pixels, int count)
Set many pixels to the default value (typically 0) For multi-component pixels, this zeros all compone...
Definition: utility.h:105