Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ImageOperators.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003, 2004 (see file CONTACTS for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <Base/Image/Image.hh>
26 #include <Base/Image/ImageConvert.hh>
27 
28 // disabled warnings
29 #include <Base/Common/BIASpragma.hh>
30 
31 
32 namespace BIAS {
33 
34 //////////////////////////////////////////////////////////////////////////////
35 //
36 // Assignment Operator
37 //
38 //////////////////////////////////////////////////////////////////////////////
39 
40 template <class StorageType>
42 {
43 #ifdef BIAS_DEBUG
44  _liDebugLevel = Source.GetDebugLevel();
45  BIASGDOUT(D_IMAGE_TRACE,
46  "called Image::operator=(const ImageBase& Source)"
47  <<" source->GetStorageType = "<<Source.GetStorageType()
48  <<" this->GetStorageType = "<<GetStorageType()
49  <<" this->TemplateType = "<<PRINTTYPE(StorageType));
50 #endif
51  if (GetStorageType()==Source.GetStorageType()){
52  this->ImageBase::operator=(Source);
53  } else {
54  // please ensure that TestImageAssign runs flawless when changing anything
55  // in this function
56  BEXCEPTION("Images have different storage type. Use ConvertST()");
57  }
58  return *this;
59 }
60 
61 
62 //////////////////////////////////////////////////////////////////////////////
63 //
64 //
65 // Defining Operators -, -= ,+ ,+= ,* ,*= ,/ ,/= for both a scalar argument and an image
66 //
67 // These operators are templated, so the work only on arguments of the same
68 // type as the image itself.
69 //
70 // The division operators have an addition a test for
71 // - a zero scalar as argument
72 // - for zero values in an argument image (if MIP_BOUNCE_CHECK is defined)
73 //
74 //
75 //////////////////////////////////////////////////////////////////////////////
76 
77 //
78 // As long as color images are not supported, exit if operation is tried on non-gray images
79 //
80 #ifdef BIAS_DEBUG
81 #define GRAYTEST(OPERATOR) \
82 if (GetChannelCount() != 1) { \
83  BIASERR("Operation " << OPERATOR << " is only defined on gray images. Leaving images unchanged! Aborting!"); \
84  BIASBREAK;\
85  BIASABORT; \
86 }
87 #else
88 #define GRAYTEST(OPERATOR)
89 #endif
90 
91 
92 //////////////////////////////////////////////////////////////////////////////
93 
94 
95 /// Test the the dimensions of the ROI of two images. If both have none
96 /// test the dimensions of the whole image
97 /// Abort in any case of error.
98 template <class StorageType>
100  const Image<StorageType>& i2)
101 {
102  // Test for matching dimensions of ROI
103  if ( ( (i1.GetROILowerRightX() - i1.GetROIUpperLeftX()) !=
104  (i2.GetROILowerRightX() - i2.GetROIUpperLeftX()) ) ||
105  ( (i1.GetROILowerRightY() - i1.GetROIUpperLeftY()) !=
106  (i2.GetROILowerRightY() - i2.GetROIUpperLeftY()) ) ) {
107  BIASERR("Computation not possible: 'Region Of Interest' do not "
108  <<"match in size! Aborting!");
109  i1.PrintROI();
110  i2.PrintROI();
111  return false;
112  }
113  return true;
114 }
115 
116 
117 //////////////////////////////////////////////////////////////////////////////
118 //
119 // The unary operators on pixel values of an image using a scalar
120 //
121 //////////////////////////////////////////////////////////////////////////////
122 
123 /** Operator += with scalar on pixel values of an image */
124 template <class StorageType>
126 {
127  GRAYTEST("+=");
128 
129  unsigned int minx, miny, maxx, maxy;
130  GetROICorners(minx, miny, maxx, maxy);
131  register int width=(int)GetWidth(), step=width-maxx+minx;
132  /*register*/ StorageType *p=GetImageData()+width*miny+minx;
133  /*register*/ StorageType *le=GetImageData()+width*miny+maxx;
134  /*register*/ StorageType *e=GetImageData()+width*(maxy-1)+maxx;
135  while (p<e){
136  while (p<le){ // walk one line
137  //*p++ += Value;
138 
139  (*p) += (Value);
140  //*p = *p + Value;
141 
142  p++;
143  }
144  le+=width; // skip to beginning of next line
145  p+=step;
146  }
147 
148  return *this;
149 }
150 
151 
152 /** Operator -= with scalar on pixel values of an image */
153 template <class StorageType>
155 {
156  GRAYTEST("-=");
157 
158  unsigned int minx, miny, maxx, maxy;
159  GetROICorners(minx, miny, maxx, maxy);
160  register int width=(int)GetWidth(), step=width-maxx+minx;
161  register StorageType *p=GetImageData()+width*miny+minx;
162  register StorageType *le=GetImageData()+width*miny+maxx;
163  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
164  while (p<e){
165  while (p<le){ // walk one line
166  *p++ -= Value;
167  }
168  le+=width; // skip to beginning of next line
169  p+=step;
170  }
171 
172  return *this;
173 }
174 
175 
176 /** Operator *= with scalar on pixel values of an image */
177 template <class StorageType>
179 {
180  GRAYTEST("*=");
181 
182  unsigned int minx, miny, maxx, maxy;
183  GetROICorners(minx, miny, maxx, maxy);
184  register int width=(int)GetWidth(), step=width-maxx+minx;
185  width *= GetChannelCount();
186  step *= GetChannelCount();
187  register StorageType *p = GetImageData()+width*miny +minx;
188  register StorageType *le = GetImageData()+width*miny +maxx;
189  register StorageType *e = GetImageData()+width*(maxy-1) +maxx;
190  while (p<e){
191  while (p<le){ // walk one line
192  *p++ *= Value;
193  }
194  le+=width; // skip to beginning of next line
195  p+=step;
196  }
197 
198  return *this;
199 }
200 
201 
202 /** Operator /= with scalar on pixel values of an image */
203 template <class StorageType>
205 {
206  if (Value == (StorageType) 0) {
207  BIASERR("Division by zero attempted on image. Aborting!");
208  BIASABORT;
209  }
210 
211  // GRAYTEST("/=");
212 
213  unsigned int minx, miny, maxx, maxy;
214  GetROICorners(minx, miny, maxx, maxy);
215  register int width=(int)GetWidth(), step=width-maxx+minx;
216  register StorageType *p=GetImageData()+width*miny+minx;
217  register StorageType *le=GetImageData()+width*miny+maxx;
218  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
219  while (p<e){
220  while (p<le){ // walk one line
221  *p++ /= Value;
222  }
223  le+=width; // skip to beginning of next line
224  p+=step;
225  }
226 
227  return *this;
228 }
229 
230 
231 
232 //////////////////////////////////////////////////////////////////////////////
233 //
234 // The unary operators on pixel values of an image using the pixel
235 // values of another image
236 //
237 //////////////////////////////////////////////////////////////////////////////
238 
239 /** Operator += operating on pixel values with pixel values of another image */
240 template <class StorageType>
243 {
244  GRAYTEST("+=");
245 
246  unsigned int minx, miny, maxx, maxy;
247  GetROICorners(minx, miny, maxx, maxy);
248  register int width=(int)GetWidth(), step=width-maxx+minx;
249  register StorageType *p=GetImageData()+width*miny+minx;
250  register StorageType *le=GetImageData()+width*miny+maxx;
251  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
252  register const StorageType *argimagedata=argimage.GetImageData()+width*miny+minx;
253  while (p<e){
254  while (p<le){ // walk one line
255  *p++ += *argimagedata++;
256  }
257  le+=width; // skip to beginning of next line
258  p+=step;
259  argimagedata+=step;
260  }
261 
262  return *this;
263 }
264 
265 /** Operator -= operating on pixel values with pixel values of another image */
266 template <class StorageType> Image<StorageType>&
268 {
269  GRAYTEST("+=");
270 
271  unsigned int minx, miny, maxx, maxy;
272  GetROICorners(minx, miny, maxx, maxy);
273  register int width=(int)GetWidth(), step=width-maxx+minx;
274  register StorageType *p=GetImageData()+width*miny+minx;
275  register StorageType *le=GetImageData()+width*miny+maxx;
276  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
277  register const StorageType *argimagedata=argimage.GetImageData()+width*miny+minx;
278  while (p<e){
279  while (p<le){ // walk one line
280  *p++ -= *argimagedata++;
281  }
282  le+=width; // skip to beginning of next line
283  p+=step;
284  argimagedata+=step;
285  }
286 
287  return *this;
288 }
289 
290 /** Operator *= operating on pixel values with pixel values of another image */
291 template <class StorageType> Image<StorageType>&
293 {
294  GRAYTEST("+=");
295 
296  unsigned int minx, miny, maxx, maxy;
297  GetROICorners(minx, miny, maxx, maxy);
298  register int width=(int)GetWidth(), step=width-maxx+minx;
299  register StorageType *p=GetImageData()+width*miny+minx;
300  register StorageType *le=GetImageData()+width*miny+maxx;
301  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
302  register const StorageType *argimagedata=argimage.GetImageData()+width*miny+minx;
303  while (p<e){
304  while (p<le){ // walk one line
305  *p++ *= *argimagedata++;
306  }
307  le+=width; // skip to beginning of next line
308  p+=step;
309  argimagedata+=step;
310  }
311 
312  return *this;
313 }
314 
315 /** Operator /= operating on pixel values with pixel values of another image */template <class StorageType> Image<StorageType>&
317 {
318  GRAYTEST("+=");
319 
320  unsigned int minx, miny, maxx, maxy;
321  GetROICorners(minx, miny, maxx, maxy);
322  register int width=(int)GetWidth(), step=width-maxx+minx;
323  register StorageType *p=GetImageData()+width*miny+minx;
324  register StorageType *le=GetImageData()+width*miny+maxx;
325  register StorageType *e=GetImageData()+width*(maxy-1)+maxx;
326  register const StorageType *argimagedata=argimage.GetImageData()+width*miny+minx;
327  while (p<e){
328  while (p<le){ // walk one line
329  if(*argimagedata != (StorageType) 0)
330  *p /= *argimagedata;
331  argimagedata++;
332  p++;
333  }
334  le+=width; // skip to beginning of next line
335  p+=step;
336  argimagedata+=step;
337  }
338 
339  return *this;
340 }
341 
342 //////////////////////////////////////////////////////////////////////////////
343 //
344 // The binary operators on pixel values of an image using a scalar
345 //
346 //////////////////////////////////////////////////////////////////////////////
347 
348 
349 /** Binary operator + operating on pixel values with a scalar,
350  returning a new image */
351 template <class StorageType>
352 Image<StorageType> Image<StorageType>::operator+ (const StorageType& Value) const
353 {
354  if (Value == (StorageType) 0) {
355  BIASERR("Division by zero attempted on image. Aborting!");
356  BIASABORT;
357  }
358 
359  GRAYTEST("+");
360 
361  /* In any case we need a new result image */
362  Image<StorageType> result;
363  result.Init(GetWidth(), GetHeight(), GetChannelCount());
364 
365  /* Define a new result image and use the unary version of this operator */
366  result = (*this);
367  result += Value;
368 
369  return result;
370 }
371 
372 
373 /** Binary operator - operating on pixel values with a scalar,
374  returning a new image */
375 template <class StorageType>
376 Image<StorageType> Image<StorageType>::operator- (const StorageType& Value) const
377 {
378  GRAYTEST("-");
379 
380  /* In any case we need a new result image */
381  Image<StorageType> result(GetWidth(), GetHeight(), GetChannelCount());
382 
383  /* Define a new result image and use the unary version of this operator */
384  result = (*this);
385  result -= Value;
386 
387  return result;
388 }
389 
390 
391 /** Binary operator * operating on pixel values with a scalar,
392  returning a new image */
393 template <class StorageType>
394 Image<StorageType> Image<StorageType>::operator* (const StorageType& Value) const
395 {
396  GRAYTEST("*");
397 
398  /* In any case we need a new result image */
399  Image<StorageType> result(GetWidth(), GetHeight(), GetChannelCount());
400 
401  /* Define a new result image and use the unary version of this operator */
402  result = (*this);
403  result *= Value;
404 
405  return result;
406 }
407 
408 
409 /** Binary operator / operating on pixel values with a scalar,
410  returning a new image */
411 template <class StorageType>
412 Image<StorageType> Image<StorageType>::operator/ (const StorageType& Value) const
413 {
414  GRAYTEST("/");
415 
416  /* In any case we need a new result image */
417  Image<StorageType> result;
418  result.Init(GetWidth(), GetHeight(), GetChannelCount());
419 
420  /* Define a new result image and use the unary version of this operator */
421  result = (*this);
422  result /= Value;
423 
424  return result;
425 }
426 
427 
428 //////////////////////////////////////////////////////////////////////////////
429 //
430 // The binary operators on pixel values of an image using pixel values of
431 // another image, returning a new image
432 //
433 //////////////////////////////////////////////////////////////////////////////
434 
435 /** Binary Operator + operating pixel values with pixel values of another
436  image, returning a new image */
437 template <class StorageType> Image<StorageType>
439 {
440  GRAYTEST("+");
441 
442  /* In any case we need a new result image */
443  Image<StorageType> result;
444  result.Init(argimage.GetWidth(), argimage.GetHeight(),
445  argimage.GetChannelCount());
446 
447 
448  if ( HaveImagesMatchingROI(*this, argimage) ) {
449  /* Define a new result image and use the unary version of this operator */
450  result = (*this);
451  result += argimage;
452  } else {
453  BIASERR("unmatching ROIs");
454  }
455  return result;
456 }
457 
458 
459 /** Binary Operator - operating pixel values with pixel values of another
460  image, returning a new image */
461 template <class StorageType> Image<StorageType>
463 {
464  GRAYTEST("-");
465 
466  /* In any case we need a new result image */
467  Image<StorageType> result;
468  result.Init(argimage.GetWidth(), argimage.GetHeight(),
469  argimage.GetChannelCount());
470 
471  if ( HaveImagesMatchingROI(*this, argimage) ) {
472  /* Define a new result image and use the unary version of this operator */
473  result = *this;
474  result -= argimage;
475  } else {
476  BIASERR("unmatching ROIs");
477  }
478  return result;
479 }
480 
481 
482 /** Binary Operator * operating pixel values with pixel values of another
483  image, returning a new image */
484 template <class StorageType> Image<StorageType>
486 {
487  GRAYTEST("*");
488 
489  /* In any case we need a new result image */
490  Image<StorageType> result;
491  result.Init(argimage.GetWidth(), argimage.GetHeight(),
492  argimage.GetChannelCount());
493 
494  if ( HaveImagesMatchingROI(*this, argimage) ) {
495 
496  /* Define a new result image and use the unary version of this operator */
497  result = (*this);
498  result *= argimage;
499  } else {
500  BIASERR("unmatching ROIs");
501  }
502  return result;
503 }
504 
505 
506 /** Binary Operator / operating pixel values with pixel values of another
507  image, returning a new image */
508 template <class StorageType> Image<StorageType>
510 {
511  GRAYTEST("/");
512 
513  /* In any case we need a new result image */
514  Image<StorageType> result;
515  result.Init(argimage.GetWidth(), argimage.GetHeight(),
516  argimage.GetChannelCount());
517 
518  if ( HaveImagesMatchingROI(*this, argimage) ) {
519  /* Define a new result image and use the unary version of this operator */
520  result = (*this);
521  result /= argimage;
522  } else {
523  BIASERR("unmatching ROIs");
524  }
525  return result;
526 }
527 
528 
529 
530 /** logical Operator || operating pixel values with pixel values of another
531  image, returning a new image */
532 template <class StorageType> Image<StorageType>&
534 {
535  BIASERR("operator| not implemented for StorageType");
536  return *(Image<StorageType>*)NULL;
537 }
538 
539 template <> Image<short int>&
541 {
542  GRAYTEST("|");
543 
544  /* In any case we need a new result image */
545  Image<short int>& result = *(new Image<short int>);
546  result.Init(argimage.GetWidth(), argimage.GetHeight(),
547  argimage.GetChannelCount());
548 
549  if ( HaveImagesMatchingROI(*this, argimage) ) {
550  BIASERR("Image::operator| not implemented for images with ROIs");
551  } else {
552  BIASERR("unmatching ROIs");
553 // /* Get the pointer to the begin of the image (and of the newly created result image) and use it as counter */
554 // register short int* ImageData = (short int*)GetImageData();
555 // register short int* ImageDataStop = ImageData + GetPixelCount();
556 // register short int* ArgImageData = (short int*)argimage.GetImageData();
557 // register short int* ResultImageData= (short int*)result.GetImageData();
558 // for(;ImageData < ImageDataStop; ImageData++,
559 // ArgImageData++, ResultImageData++) {
560 // *ResultImageData = *ImageData | *ArgImageData;
561 // }
562  }
563  return result;
564 }
565 
566 template <> Image<unsigned char>&
568 {
569  GRAYTEST("|");
570 
571  /* In any case we need a new result image */
573  result.Init(argimage.GetWidth(), argimage.GetHeight(),
574  argimage.GetChannelCount());
575 
576  if ( HaveImagesMatchingROI(*this, argimage) ) {
577  BIASERR("Image::operator| not implemented for images with ROIs");
578  } else {
579  BIASERR("unmatching ROIs");
580 // /* Get the pointer to the begin of the image (and of the newly created result image) and use it as counter */
581 // register unsigned char* ImageData = (unsigned char* )GetImageData();
582 // register unsigned char* ImageDataStop = ImageData + GetPixelCount();
583 // register unsigned char* ArgImageData =
584 // (unsigned char* )argimage.GetImageData();
585 // register unsigned char* ResultImageData=
586 // (unsigned char* )result.GetImageData();
587 // for(;ImageData < ImageDataStop; ImageData++,
588 // ArgImageData++, ResultImageData++) {
589 // *ResultImageData = *ImageData | *ArgImageData;
590 // }
591  }
592  return result;
593 }
594 
595 
596 /** absolut difference */
597 template <class StorageType> void
599  const Image<StorageType>& im2)
600 {
601 #ifdef BIAS_DEBUG
602  if (!im1.SamePixelAndChannelCount(im2))
603  BIASERR("images are not of same size or channelcount");
604 #endif
605  if (!IsEmpty()) Release();
606  Init(im1.GetWidth(), im1.GetHeight(), im1.GetChannelCount());
607  unsigned int cc = im1.GetChannelCount();
608 
609  /* Do the image dimensions (or the ROI dimensions if both images have one)
610  fit */
611  if ( HaveImagesMatchingROI(im1, im2) ) {
612  unsigned minx, miny, maxx, maxy;
613  im1.GetROICorners(minx, miny, maxx, maxy);
614  StorageType **ida=GetImageDataArray();
615  const StorageType **ida1=im1.GetImageDataArray();
616  const StorageType **ida2=im2.GetImageDataArray();
617  maxx *= cc;
618  for (unsigned y=miny; y<maxy; y++){
619  for (unsigned x=minx; x<maxx; x+= cc){
620  for (unsigned int c=0;c<cc; c++) {
621  ida[y][x+c]=(ida1[y][x+c]>ida2[y][x+c])?
622  (ida1[y][x+c]-ida2[y][x+c]):(ida2[y][x+c]-ida1[y][x+c]);
623  }
624  }
625  }
626  } else {
627  BIASERR("unmatching ROIs");
628  }
629 }
630 
631 //////////////////////////////////////////////////////////////////////////////
632 
633 
634 
635 } // namespace BIAS
const unsigned int GetROIUpperLeftX() const
deprecated, use GetROI()-&gt;GetCorners()
Definition: ImageBase.cpp:1092
ImageBase & operator=(const ImageBase &Source)
assignment operator, allocates memory structure via Init only if necessary
Definition: ImageBase.cpp:745
Image< StorageType > & operator-=(const StorageType &argimage)
Operator -= for scalar value.
Image< StorageType > & operator+=(const StorageType &argimage)
Operator += for scalar value.
unsigned int GetWidth() const
Definition: ImageBase.hh:312
const unsigned int GetROIUpperLeftY() const
deprecated, use GetROI()-&gt;GetCorners()
Definition: ImageBase.cpp:1099
Image< StorageType > & operator|(const Image< StorageType > &argimage)
logical Operator || operating pixel values with pixel values of another image, returning a new image ...
const unsigned int GetROILowerRightY() const
deprecated, use GetROI()-&gt;GetCorners()
Definition: ImageBase.cpp:1113
int GetDebugLevel() const
Definition: Debug.hh:332
void GetROICorners(unsigned int &UpperLeftX, unsigned int &UpperLeftY, unsigned int &LowerRightX, unsigned int &LowerRightY) const
access region of interest rectangle JW
Definition: ImageBase.cpp:1067
Image< StorageType > operator/(const StorageType &argimage) const
Operator / for scalar value, returning a new image.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
Image< StorageType > operator-(const StorageType &argimage) const
Operator - for scalar value, returning a new image.
The image template class for specific storage types.
Definition: Image.hh:78
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
Image< StorageType > operator*(const StorageType &argimage) const
Operator * for scalar value, returning a new image.
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
Image< StorageType > & operator=(const ImageBase &Source)
copies ImageBase to an desired Image&lt;&gt;, be careful with this, because u can do something like: Image&lt;...
bool HaveImagesMatchingROI(const Image< StorageType > &i1, const Image< StorageType > &i2)
Test the the dimensions of the ROI of two images.
Image< StorageType > operator+(const StorageType &argimage) const
Operator + for scalar value, returning a new image.
const unsigned int GetROILowerRightX() const
deprecated, use GetROI()-&gt;GetCorners()
Definition: ImageBase.cpp:1106
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
Image< StorageType > & operator/=(const StorageType &argimage)
Operator /= for scalar value.
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
void PrintROI(std::ostream &os=std::cout) const
deprecated, use &#39;os &lt;&lt; *GetROI()&#39;
Definition: ImageBase.cpp:1087
Image< StorageType > & operator*=(const StorageType &argimage)
Operator *= for scalar value.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153