24 #include <Base/Common/W32Compat.hh>
25 #include <Base/Common/BIASpragmaStart.hh>
27 template <
class StorageType>
inline StorageType Image<StorageType>::MaxSTValue()
29 BIASERR(
"no such StorageType");
30 return (StorageType)0;
34 {
return (
unsigned char)(UCHAR_MAX); }
39 #ifdef BUILD_IMAGE_CHAR
42 template <>
inline char Image<char>::MinSTValue()
45 #ifdef BUILD_IMAGE_SHORT
46 template <>
inline short Image<short>::MaxSTValue()
48 template <>
inline short Image<short>::MinSTValue()
51 #ifdef BUILD_IMAGE_USHORT
52 template <>
inline unsigned short Image<unsigned short>::MaxSTValue()
54 template <>
inline unsigned short Image<unsigned short>::MinSTValue()
57 #ifdef BUILD_IMAGE_INT
58 template <>
inline int Image<int>::MaxSTValue()
60 template <>
inline int Image<int>::MinSTValue()
63 #ifdef BUILD_IMAGE_UINT
64 template <>
inline unsigned int Image<unsigned int>::MaxSTValue()
66 template <>
inline unsigned int Image<unsigned int>::MinSTValue()
69 #ifdef BUILD_IMAGE_DOUBLE
70 template <>
inline double Image<double>::MaxSTValue()
72 template <>
inline double Image<double>::MinSTValue()
76 template <
class StorageType>
inline StorageType Image<StorageType>::MinSTValue()
78 BIASERR(
"no such StorageType");
79 return (StorageType)0;
89 template <
class StorageType>
92 const unsigned short int channel)
const
94 CheckCoordinates((
int)x, (
int)y,
"PixelValue");
97 return GetImageData()[channel * GetPixelCount() + y * GetWidth() + x];
99 return GetImageData()[GetChannelCount() *
100 ( y * GetWidth() + x ) + channel ];
104 template <
class StorageType>
105 inline StorageType Image<StorageType>::
106 PixelValueInterleaved(
const int x,
const int y,
const int channel)
const
108 BIASASSERT(this->IsInterleaved());
109 CheckCoordinates(x, y,
"PixelValueInterleaved");
111 return GetImageDataArray()[y][x*GetChannelCount()+channel];
115 template <
class StorageType>
116 inline StorageType & Image<StorageType>::
117 PixelValueRefInterleaved(
const int x,
const int y,
const int channel)
119 BIASASSERT(this->IsInterleaved());
120 CheckCoordinates(x, y,
"PixelValueRefInterleaved");
122 return GetImageDataArray()[y][x*GetChannelCount()+channel];
126 template <
class StorageType>
127 inline const StorageType& Image<StorageType>::GetPixelNearestNeighbor(
128 const double x,
const double y,
const unsigned short int channel)
const
130 int x_res = (int) ((x - floor(x)) <= 0.5 ? floor(x) : floor(x) + 1);
131 int y_res = (int) ((y - floor(y)) <= 0.5 ? floor(y) : floor(y) + 1);
133 CheckCoordinates(x_res, y_res,
"GetNearestNeighbor");
139 GetImageData()[GetPixelCount()*channel + x_res + GetWidth() * y_res];
144 GetImageData()[GetChannelCount()*(x_res+GetWidth()*y_res)+channel];
149 template <
class StorageType>
150 inline const StorageType& Image<StorageType>::GetPixelNearestNeighbor(
151 const float x,
const float y,
const unsigned short int channel)
const
155 return GetPixelNearestNeighbor((
double) x, (
double) y, channel);
169 template <
class StorageType>
171 Image<StorageType>::SetPixel(
const StorageType & value,
172 const unsigned int & x,
173 const unsigned int & y,
174 const unsigned short int channel)
176 CheckCoordinates((
int)x, (
int)y,
"SetPixel");
177 CheckChannel(channel,
"SetPixel");
179 BIASASSERT( channel<GetChannelCount() );
182 ((StorageType*)GetImageData())[channel * GetPixelCount() + y*GetWidth() +x] = value;
184 ((StorageType*)GetImageData())[GetChannelCount() * (y*GetWidth() +x) +channel ] = value;
189 template <
class StorageType>
191 Image<StorageType>::SetPixel(
const StorageType & value0,
192 const StorageType & value1,
193 const StorageType & value2,
194 const unsigned int & x,
195 const unsigned int & y )
197 CheckChannel(2,
"SetPixel");
199 SetPixel(value0, x, y, 0);
200 SetPixel(value1, x, y, 1);
201 SetPixel(value2, x, y, 2);
204 template <
class StorageType>
205 inline bool Image<StorageType>::
206 CheckBilinearInterpolation(
const double x,
const double y)
const
208 return ((floor(x) >= 0) && (floor(y) >= 0) &&
209 (ceil(x) < GetWidth()) && (ceil(y) < GetHeight()));
212 template <
class StorageType>
213 inline bool Image<StorageType>::
214 CheckBicubicInterpolation(
const double x,
const double y)
const
216 return ((floor(x) >= 1) && (floor(y) >= 1) &&
217 ((floor(x)+2) < GetWidth()) && ((floor(y)+2) < GetHeight()));
220 template <
class StorageType>
221 inline double Image<StorageType>::LinearInterpolation(
222 const unsigned int x,
const double y)
const
225 if ((x<0) || (x>(GetWidth()-1)))
226 BIASERR(
"LinearInterpolation() x out of bounds: "<<x);
227 if ((floor(y)<0) || (ceil(y)>(GetHeight()-1)))
228 BIASERR(
"LinearInterpolation() y out of bounds: "<<y);
230 double dy = y - floor(y);
231 StorageType **ImageDataArray = (StorageType**)GetImageDataArray();
233 return ((1-dy)*(double)ImageDataArray[(
unsigned int)floor(y)][x] +
234 dy*(double)ImageDataArray[(
unsigned int)ceil(y)][x]);
237 template <
class StorageType>
238 inline double Image<StorageType>::LinearInterpolation(
239 const double x,
const unsigned int y)
const
242 if ((floor(x)<0) || ((ceil(x))>GetWidth()-1))
243 BIASERR(
"LinearInterpolation() x out of bounds: "<<x);
244 if ((y<0) || (y>(GetHeight()-1)))
245 BIASERR(
"LinearInterpolation() y out of bounds: "<<y);
247 double dx = x - floor(x);
248 StorageType **ImageDataArray = (StorageType**)GetImageDataArray();
250 return ((1-dx)*(double)ImageDataArray[y][(
unsigned int)floor(x)] +
251 dx*(double)ImageDataArray[y][(
unsigned int)ceil(x)]);
254 template <
class StorageType>
255 inline double Image<StorageType>::
256 DistanceWeightedInterpolationGrey(
const double x,
const double y)
const
258 StorageType **ida = (StorageType**)GetImageDataArray();
259 unsigned int x_floor=(
unsigned int)floor(x);
260 unsigned int y_floor=(
unsigned int)floor(y);
261 unsigned int x_ceil=(
unsigned int)ceil(x);
262 unsigned int y_ceil=(
unsigned int)ceil(y);
263 StorageType ul = ida[y_floor][x_floor];
264 StorageType ur = ida[y_floor][x_ceil];
265 StorageType ll = ida[y_ceil][x_floor];
266 StorageType lr = ida[y_ceil][x_ceil];
267 double dy = y - y_floor;
268 double dx = x - x_floor;
269 double ulw, urw, llw, lrw;
271 llw=sqrt(pow(1.0-dx,2.0)+pow(dy,2.0));
272 lrw=sqrt(pow(dx,2.0)+pow(dy,2.0));
273 ulw=sqrt(pow(1.0-dx,2.0)+pow(1.0-dy,2.0));
274 urw=sqrt(pow(dx,2.0)+pow(1.0-dy,2.0));
283 return (ul*ulw + ll*llw + lr*lrw + ur*urw);
286 template <
class StorageType>
inline double Image<StorageType>::
287 BilinearInterpolationGrey(
const double x,
const double y)
const
289 StorageType **ida = (StorageType**)GetImageDataArray();
290 BIASASSERT(ida!=NULL);
291 unsigned int x_floor=(
unsigned int)floor(x);
292 unsigned int y_floor=(
unsigned int)floor(y);
293 unsigned int x_ceil=x_floor+1;
294 unsigned int y_ceil=y_floor+1;
295 StorageType *p = ida[y_floor];
296 StorageType ul = p[x_floor];
297 StorageType ur = p[x_ceil];
299 StorageType ll = p[x_floor];
300 StorageType lr = p[x_ceil];
301 double dy = y - y_floor;
302 double dx = x - x_floor;
305 double val = ul + dy*dl + dx*(ur - ul + dy*(lr - dl - ur ));
329 #define IMAGEPOINT_UP(x,y,width,height) x<=(width-1)&& y<=(height-1)
330 #define IMAGEPOINT_DOWN(x,y,width,height) x>=0&& y>=0
333 template <
class StorageType>
inline
334 double Image<StorageType>::
335 BilinearInterpolationGreyMinVal(
const double x,
const double y,
336 const StorageType & minVal)
const
338 unsigned int x_ceil=(
unsigned int)ceil(x);
339 unsigned int y_ceil=(
unsigned int)ceil(y);
340 if(!(IMAGEPOINT_UP(x_ceil, y_ceil, Width_, Height_)))
return minVal;
341 unsigned int x_floor=(
unsigned int)floor(x);
342 unsigned int y_floor=(
unsigned int)floor(y);
345 StorageType **ida = (StorageType**)GetImageDataArray();
347 StorageType ul = ida[y_floor ][x_floor ];
348 if (ul<=minVal)
return minVal;
349 StorageType ur = ida[y_floor ][x_ceil];
350 if (ur<=minVal)
return minVal;
351 StorageType ll = ida[y_ceil][x_floor ];
352 if (ll<=minVal)
return minVal;
353 StorageType lr = ida[y_ceil][x_ceil];
354 if (lr<=minVal)
return minVal;
357 double dy = y - y_floor;
358 double dx = x - x_floor;
364 + dy*dx*(ul + lr - ll - ur );
367 template <
class StorageType>
inline
368 double Image<StorageType>::
369 BilinearInterpolationGreyMaxVal(
const double x,
const double y,
370 const StorageType & maxVal)
const
372 StorageType **ida = (StorageType**)GetImageDataArray();
373 unsigned int x_floor=(
unsigned int)floor(x);
374 unsigned int y_floor=(
unsigned int)floor(y);
375 unsigned int x_ceil=(
unsigned int)ceil(x);
376 unsigned int y_ceil=(
unsigned int)ceil(y);
379 StorageType ul = ida[y_floor ][x_floor ];
380 if (ul>=maxVal)
return maxVal;
381 StorageType ur = ida[y_floor ][x_ceil];
382 if (ur>=maxVal)
return maxVal;
383 StorageType ll = ida[y_ceil][x_floor ];
384 if (ll>=maxVal)
return maxVal;
385 StorageType lr = ida[y_ceil][x_ceil];
386 if (lr>=maxVal)
return maxVal;
389 double dy = y - y_floor;
390 double dx = x - x_floor;
396 + dy*dx*(ul + lr - ll - ur );
400 template <
class StorageType>
401 inline StorageType Image<StorageType>::
402 FastBilinearInterpolationGrey(
const double x,
const double y)
const
404 const StorageType **ida = GetImageDataArray();
405 unsigned int x_floor=(
unsigned int)floor(x);
406 unsigned int y_floor=(
unsigned int)floor(y);
407 unsigned int x_ceil=(
unsigned int)ceil(x);
408 unsigned int y_ceil=(
unsigned int)ceil(y);
409 StorageType ul = ida[y_floor][x_floor];
410 StorageType ur = ida[y_floor][x_ceil];
411 StorageType ll = ida[y_ceil][x_floor];
412 StorageType lr = ida[y_ceil][x_ceil];
413 double dy = y - y_floor;
414 double dx = x - x_floor;
416 return (StorageType)(ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul + lr - ll - ur ));
421 template <>
inline unsigned char
423 const double y)
const
425 register const unsigned char **ida = GetImageDataArray();
426 register unsigned int x_floor = (
unsigned int)floor(x);
427 register unsigned int y_floor = (
unsigned int)floor(y);
428 register unsigned int x_ceil = x_floor+1;
429 register unsigned int y_ceil = y_floor+1;
430 register unsigned int ul = (
unsigned int)ida[y_floor][x_floor];
431 register unsigned int ur = (
unsigned int)ida[y_floor][x_ceil];
432 register unsigned int ll = (
unsigned int)ida[y_ceil][x_floor];
433 register unsigned int lr = (
unsigned int)ida[y_ceil][x_ceil];
434 register unsigned int dy = (
unsigned int)rint((y - y_floor)*256);
435 register unsigned int dx = (
unsigned int)rint((x - x_floor)*256);
437 return (
unsigned char)(((ul<<16) + (dy<<8)*(ll - ul) + (dx<<8)*(ur - ul) + dy*dx*(ul - ll - ur + lr))>>16);
442 unsigned int channel)
const
444 StorageType **ida = ((StorageType**)GetImageDataArray())+channel*GetPixelCount();
445 unsigned int x_floor=(
unsigned int)floor(x);
446 unsigned int y_floor=(
unsigned int)floor(y);
447 unsigned int x_ceil=(
unsigned int)ceil(x);
448 unsigned int y_ceil=(
unsigned int)ceil(y);
449 StorageType ul = ida[y_floor][x_floor];
450 StorageType ur = ida[y_floor][x_ceil];
451 StorageType ll = ida[y_ceil][x_floor];
452 StorageType lr = ida[y_ceil][x_ceil];
453 double dy = y - y_floor;
454 double dx = x - x_floor;
456 return ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul - ll - ur + lr);
459 template <
class StorageType>
inline double Image<StorageType>::
460 BilinearInterpolationRGBInterleaved(
const double x,
const double y,
461 unsigned int channel)
const
463 unsigned int x_floor=(
unsigned int)floor(x);
464 unsigned int y_floor=(
unsigned int)floor(y);
465 unsigned int x_ceil=(
unsigned int)ceil(x);
466 unsigned int y_ceil=(
unsigned int)ceil(y);
468 ((StorageType**)GetImageDataArray())[y_floor][x_floor*
469 GetChannelCount()+channel];
471 ((StorageType**)GetImageDataArray())[y_floor][x_ceil*
472 GetChannelCount()+channel];
474 ((StorageType**)GetImageDataArray())[y_ceil][x_floor*
475 GetChannelCount()+channel];
477 ((StorageType**)GetImageDataArray())[y_ceil][x_ceil*
478 GetChannelCount()+channel];
479 double dy = y - y_floor;
480 double dx = x - x_floor;
482 return ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul - ll - ur + lr);
488 unsigned int hws_x,
unsigned int hws_y,
489 unsigned char* buffer)
492 if (ChannelCount_!=1) {
493 BIASERR(
"invalid channel count != 1: channels="<<ChannelCount_);
510 const unsigned char **ida = (
const unsigned char**)GetImageDataArray();
513 const unsigned int x_floor = (
unsigned int)floor(x) - hws_x;
514 const unsigned int y_floor = (
unsigned int)floor(y) - hws_y;
515 const unsigned int x_ceil = (
unsigned int)ceil(x) - hws_x;
516 const unsigned int y_ceil = (
unsigned int)ceil(y) - hws_y;
519 register unsigned char* ul = (
unsigned char*) &ida[y_floor ][x_floor ];
520 register unsigned char* ur = (
unsigned char*) &ida[y_floor ][x_ceil];
521 register unsigned char* ll = (
unsigned char*) &ida[y_ceil][x_floor ];
522 register unsigned char* lr = (
unsigned char*) &ida[y_ceil][x_ceil];
525 register unsigned char* result = buffer;
528 const double dy = y - floor(y);
529 const double dx = x - floor(x);
530 const double dxdy = dx*dy;
533 const unsigned int countx = 2*hws_x+1;
534 const unsigned int county = 2*hws_y+1;
535 const unsigned int lineoffset = GetWidth()-1-2*hws_x;
538 for (
unsigned int iy = 0; iy< county; iy++) {
539 for (
unsigned int ix = 0; ix< countx; ix++, ul++, ur++, ll++, lr++) {
540 *result = (
unsigned char)(*ul + dy*(*ll - *ul) + dx*(*ur - *ul) + dxdy*(*ul + *lr - *ll - *ur));
552 template <
class StorageType>
555 unsigned int hws_x,
unsigned int hws_y,
558 BIASERR(
"BilinearInterpolationShiftRegion is not implemented for other "
559 "storage types than unsigned char!");
563 #include <Base/Common/BIASpragmaEnd.hh>
void BilinearInterpolationShiftRegion(const double &x, const double &y, unsigned int hws_x, unsigned int hws_y, unsigned char *buffer)
Interpolate shifted rectangular region centered at given subpixel position.
The image template class for specific storage types.