Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Convolution.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2004 (see file CONTACT for details)
5  Johan Skoglund
6  skoglund@isy.liu.se
7  CVL/isy
8  university of Linkoeping
9  sweden
10 
11  Multimediale Systeme der Informationsverarbeitung
12  Institut fuer Informatik
13  Christian-Albrechts-Universitaet Kiel
14 
15 BIAS is free software; you can redistribute it and/or modify
16 it under the terms of the GNU Lesser General Public License as published by
17 the Free Software Foundation; either version 2.1 of the License, or
18 (at your option) any later version.
19 
20 BIAS is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU Lesser General Public License for more details.
24 
25 You should have received a copy of the GNU Lesser General Public License
26 along with BIAS; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29 
30 /// \todo This file contains no kind of optimization at all for the moment.
31 /// To be added later on
32 
33 #include "Convolution.hh"
34 
35 #ifdef BIAS_DEBUG
36 #include "Base/Image/ImageIO.hh"
37 #endif
38 
39 #include <Base/Common/BIASpragma.hh>
40 
41 using namespace BIAS;
42 using namespace std;
43 
44 //calculates the center pixel in the convolution kernel.
45 #define KERNCENTER(thesize) ((thesize-1)>>1)
46 
47 
48 template <class InputStorageType,class OutputStorageType>
51 {
52  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvIntMat_\n");
53  const InputStorageType **srcstart=src.GetImageDataArray();
54  OutputStorageType **dststart=dst.GetImageDataArray();
55  const Matrix<FM_INT> *kernel=_fm.GetKerneli();
56  int kern_width=kernel->GetCols();
57  int kern_height=kernel->GetRows();
58  int img_width=src.GetWidth();
59  int img_height=src.GetHeight();
60  int channelcount=src.GetChannelCount();
61 
62  int kern_center_x=KERNCENTER(kern_width);
63  int kern_center_y=KERNCENTER(kern_height);
64 
65  signed char rightshift=_fm.GetKernelRightShift();
66  const InputStorageType **srcida = NULL;
67  OutputStorageType **dstida = NULL;
68 
69  // distance between neighboring pixels in storagetypes
70  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
71 
72  int offset = 0;
73  for(int chloop=0;chloop<channelcount;chloop++) {
74  if (src.IsInterleaved()) {
75  srcida = srcstart;
76  dstida = dststart;
77  // ida[y][PixelSpacing*x] gives first channel, need an offset
78  offset = chloop;
79  } else {
80  // get start of plane:
81  srcida = srcstart + chloop*img_height;
82  dstida = dststart + chloop*img_height;
83  offset = 0;
84  }
85  for(int img_x=0;img_x<img_width;img_x++)
86  for(int img_y=0;img_y<img_height;img_y++) {
87  register CONV_INT sum=0;
88  for(int kern_x=0;kern_x<kern_width;kern_x++)
89  for(int kern_y=0;kern_y<kern_height;kern_y++) {
90  //kern_center_x-kern_x -> img_offset
91  int img_offset_x=kern_center_x-kern_x;
92  int img_offset_y=kern_center_y-kern_y;
93  if(img_offset_x+img_x<0)
94  continue;
95  if(img_offset_y+img_y<0)
96  continue;
97  if(img_x+img_offset_x>=img_width)
98  continue;
99  if(img_y+img_offset_y>=img_height)
100  continue;
101  sum +=(CONV_INT) (srcida[img_y+img_offset_y][(img_x+img_offset_x)
102  *PixelSpacing+offset]*
103  ((*kernel)[kern_y][kern_x]));
104  }
105  dstida[img_y][img_x*PixelSpacing+offset]=
106  (OutputStorageType)((sum)>>rightshift);
107  }
108  }
109 
110  return 0;
111 }
112 
113 template <class InputStorageType,class OutputStorageType>
116 {
117  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvIntHori_\n");
118  const InputStorageType **srcstart=src.GetImageDataArray();
119  CONV_INT **dststart=dst.GetImageDataArray();
120  const Vector<FM_INT> *kernel=_fm.GetSepih();
121  int kern_width=kernel->Size();
122  int img_width=src.GetWidth();
123  int img_height=src.GetHeight();
124  int channelcount=src.GetChannelCount();
125 
126  int kern_center_x=KERNCENTER(kern_width);
127 
128  signed char rightshift=_fm.GetHorizRightShift();
129  const InputStorageType **srcida = NULL;
130  CONV_INT **dstida = NULL;
131 
132  // distance between neighboring pixels in storagetypes
133  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
134  int offset = 0;
135  for(int chloop=0;chloop<channelcount;chloop++) {
136  if (src.IsInterleaved()) {
137  srcida = srcstart;
138  dstida = dststart;
139  // ida[y][PixelSpacing*x] gives first channel, need an offset
140  offset = chloop;
141  } else {
142  // get start of plane:
143  srcida = srcstart + chloop*img_height;
144  dstida = dststart + chloop*img_height;
145  offset = 0;
146  }
147 
148  for(int img_y=0;img_y<img_height;img_y++) {
149  for(int img_x=0;img_x<img_width;img_x++) {
150  int kern_xmax=min((kern_center_x+img_x+1),kern_width);
151  int kern_xmin=max(0,(img_x+kern_center_x-img_width+1));
152  register CONV_INT sum=0;
153 
154  for(int kern_x=kern_xmin;kern_x<kern_xmax;kern_x++) {
155  int img_offset_x=kern_center_x-kern_x;
156  sum +=
157  (CONV_INT)(srcida[img_y][(img_x+img_offset_x)*PixelSpacing+offset])
158  *((*kernel)[kern_x]);
159  }
160  dstida[img_y][img_x*PixelSpacing+offset] =
161  (CONV_INT)((sum)>>rightshift);
162  }
163  }
164  }
165 
166  return 0;
167 }
168 
169 template <class InputStorageType,class OutputStorageType>
172 {
173  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvIntVert_\n");
174  const CONV_INT **srcstart=src.GetImageDataArray();
175  OutputStorageType **dststart=dst.GetImageDataArray();
176  const Vector<FM_INT> *kernel=_fm.GetSepiv();
177  int kern_height=kernel->Size();
178  int img_width=src.GetWidth();
179  int img_height=src.GetHeight();
180  int channelcount=src.GetChannelCount();
181 
182  int kern_center_y=KERNCENTER(kern_height);
183 
184  signed char rightshift=_fm.GetVertRightShift();
185  const CONV_INT **srcida = NULL;
186  OutputStorageType **dstida = NULL;
187 
188  // distance between neighboring pixels in storagetypes
189  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
190 
191  int offset = 0;
192 
193  for(int chloop=0;chloop<channelcount;chloop++) {
194  if (src.IsInterleaved()) {
195  srcida = srcstart;
196  dstida = dststart;
197  // ida[y][PixelSpacing*x] gives first channel, need an offset
198  offset = chloop;
199  } else {
200  // get start of plane:
201  srcida = srcstart + chloop*img_height;
202  dstida = dststart + chloop*img_height;
203  offset = 0;
204  }
205 
206  for(int img_y=0;img_y<img_height;img_y++) {
207  int kern_ymax=min((kern_center_y+img_y+1),kern_height);
208  int kern_ymin=max(0,(img_y+kern_center_y-img_height+1));
209 
210  for(int img_x=0;img_x<img_width;img_x++) {
211  register CONV_INT sum=0;
212  for(int kern_y=kern_ymin;kern_y<kern_ymax;kern_y++) {
213  int img_offset_y=kern_center_y-kern_y;
214  sum +=
215  (CONV_INT)(srcida[img_y+img_offset_y][img_x*PixelSpacing+offset])*
216  ((*kernel)[kern_y]);
217  }
218  dstida[img_y][img_x*PixelSpacing+offset]=
219  (OutputStorageType)((sum)>>rightshift);
220  }
221  }
222  }
223  return 0;
224 }
225 
226 template <class InputStorageType,class OutputStorageType>
229  Image<OutputStorageType> &dst) {
230  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvFloatMat_\n");
231  const InputStorageType **srcstart = src.GetImageDataArray();
232  OutputStorageType **dststart = dst.GetImageDataArray();
233  const Matrix<FM_FLOAT> *kernel=_fm.GetKernelf();
234  const int kern_width = kernel->GetCols();
235  const int kern_height = kernel->GetRows();
236  const int img_width = src.GetWidth();
237  const int img_height = src.GetHeight();
238  const int channelcount = src.GetChannelCount();
239  const int kern_center_x = KERNCENTER(kern_width);
240  const int kern_center_y = KERNCENTER(kern_height);
241 
242  const InputStorageType **srcida = NULL;
243  OutputStorageType **dstida = NULL;
244 
245  // distance between neighboring pixels in storagetypes
246  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
247 
248  int offset = 0;
249  for(int chloop=0;chloop<channelcount;chloop++) {
250  if (src.IsInterleaved()) {
251  srcida = srcstart;
252  dstida = dststart;
253  // ida[y][PixelSpacing*x] gives first channel, need an offset
254  offset = chloop;
255  } else {
256  // get start of plane:
257  srcida = srcstart + chloop*img_height;
258  dstida = dststart + chloop*img_height;
259  offset = 0;
260  }
261  for(int img_x=0;img_x<img_width;img_x++)
262  for(int img_y=0;img_y<img_height;img_y++) {
263  register CONV_FLOAT sum=0;
264  for(int kern_x=0;kern_x<kern_width;kern_x++)
265  for(int kern_y=0;kern_y<kern_height;kern_y++) {
266  //kern_center_x-kern_x -> img_offset
267  int img_offset_x=kern_center_x-kern_x*PixelSpacing;
268  int img_offset_y=kern_center_y-kern_y;
269  if(img_offset_x+img_x<0)
270  continue;
271  if(img_offset_y+img_y<0)
272  continue;
273  if(img_x+img_offset_x>=img_width)
274  continue;
275  if(img_y+img_offset_y>=img_height)
276  continue;
277  sum += (CONV_FLOAT)srcida[img_y+img_offset_y][(img_x+img_offset_x)*
278  PixelSpacing+offset]
279  * ((*kernel)[kern_y][kern_x]);
280  }
281  dstida[img_y][img_x*PixelSpacing+offset] = (OutputStorageType)sum;
282  }
283  }
284 
285  return 0;
286 }
287 
288 template <class InputStorageType,class OutputStorageType>
291 {
292  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvFloatHori_\n");
293  const InputStorageType **srcstart=src.GetImageDataArray();
294  CONV_FLOAT **dststart=dst.GetImageDataArray();
295  const Vector<FM_FLOAT> *kernel=_fm.GetSepfh();
296  int kern_width=kernel->Size();
297  int img_width=src.GetWidth();
298  int img_height=src.GetHeight();
299  int channelcount=src.GetChannelCount();
300 
301  int kern_center_x=KERNCENTER(kern_width);
302  const InputStorageType **srcida = NULL;
303  CONV_FLOAT **dstida = NULL;
304  int offset = 0;
305  // distance between neighboring pixels in storagetypes
306  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
307 
308 
309  for(int chloop=0;chloop<channelcount;chloop++) {
310  if (src.IsInterleaved()) {
311  srcida = srcstart;
312  dstida = dststart;
313  // ida[y][PixelSpacing*x] gives first channel, need an offset
314  offset = chloop;
315  } else {
316  // get start of plane:
317  srcida = srcstart + chloop*img_height;
318  dstida = dststart + chloop*img_height;
319  offset = 0;
320  }
321 
322 
323  for(int img_y=0;img_y<img_height;img_y++){
324  for(int img_x=0;img_x<img_width;img_x++) {
325  int kern_xmax=min((kern_center_x+img_x+1),kern_width);
326  int kern_xmin=max(0,(img_x+kern_center_x-img_width+1));
327  register CONV_FLOAT sum=0;
328  for(int kern_x=kern_xmin;kern_x<kern_xmax;kern_x++) {
329  int img_offset_x=kern_center_x-kern_x;
330  sum+=CONV_FLOAT(srcida[img_y]
331  [(img_x+img_offset_x)*PixelSpacing+offset])*
332  ((*kernel)[kern_x]);
333  }
334  dstida[img_y][img_x*PixelSpacing+offset]=(CONV_FLOAT)sum;
335  }
336  }
337  }
338 
339  return 0;
340 }
341 
342 template <class InputStorageType,class OutputStorageType>
345 {
346  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::ConvFloatVert_\n");
347  const CONV_FLOAT **srcstart=src.GetImageDataArray();
348  OutputStorageType **dststart=dst.GetImageDataArray();
349  const Vector<FM_FLOAT> *kernel=_fm.GetSepfv();
350  int kern_height=kernel->Size();
351  int img_width=src.GetWidth();
352  int img_height=src.GetHeight();
353  int channelcount=src.GetChannelCount();
354 
355  int kern_center_y=KERNCENTER(kern_height);
356  const CONV_FLOAT **srcida = NULL;
357  OutputStorageType **dstida = NULL;
358  int offset = 0;
359  // distance between neighboring pixels in storagetypes
360  const int PixelSpacing = (src.IsInterleaved())? channelcount : 1;
361  for(int chloop=0;chloop<channelcount;chloop++) {
362  if (src.IsInterleaved()) {
363  srcida = srcstart;
364  dstida = dststart;
365  // ida[y][PixelSpacing*x] gives first channel, need an offset
366  offset = chloop;
367  } else {
368  // get start of plane:
369  srcida = srcstart + chloop*img_height;
370  dstida = dststart + chloop*img_height;
371  offset = 0;
372  }
373  for(int img_y=0;img_y<img_height;img_y++) {
374  int kern_ymax=min((kern_center_y+img_y+1),kern_height);
375  int kern_ymin=max(0,(img_y+kern_center_y-img_height+1));
376  for(int img_x=0;img_x<img_width;img_x++) {
377  register CONV_FLOAT sum=0;
378  for(int kern_y=kern_ymin;kern_y<kern_ymax;kern_y++) {
379  // for(int kern_y=0;kern_y<kern_height;kern_y++) {
380  int img_offset_y=kern_center_y-kern_y;
381 
382  sum +=
383  (CONV_FLOAT)(srcida[img_y+img_offset_y][img_x*PixelSpacing+offset])
384  * ((*kernel)[kern_y]);
385 
386  }
387  dstida[img_y][img_x*PixelSpacing+offset] = (OutputStorageType)sum;
388  }
389  }
390  }
391  return 0;
392 }
393 
394 template <class InputStorageType, class OutputStorageType>
397  : FilterNToN<InputStorageType,OutputStorageType>()
398 {
399  _fm.SetZero();
400 }
401 
402 template <class InputStorageType, class OutputStorageType>
405  : FilterNToN<InputStorageType, OutputStorageType>(other), _fm(other._fm)
406 {
407 }
408 
409 template <class InputStorageType, class OutputStorageType>
411 {
412  _fm.SetZero();
413 }
414 
415 template <class InputStorageType, class OutputStorageType>
418 {
419  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::Filter\n");
420 #ifdef BIAS_DEBUG
421  if (typeid(InputStorageType)!=typeid(OutputStorageType)) {
422  BIASDOUT(D_CONV_TYPES, "Implicit storage type conversion during filtering."
423  <<" input=" << PRINTTYPE(InputStorageType)
424  <<", output=" << PRINTTYPE(OutputStorageType));
425  } else {
426  BIASDOUT(D_CONV_TYPES, "filtering same storage type: "
427  <<PRINTTYPE(InputStorageType));
428  }
429 #endif
430  // check if output image is floating point, if so, do float convolution:
431  // and also if the input image is float, we must use this, because the
432  // int mask approximation comes into trouble with float input images
433  if (CalculationInFloat()) {
434  BIASDOUT(D_CONV_TYPES,"Convolution is done with floating point numbers.");
436  }
437  // no float => integer type, do integer arithmetic convolution
438  BIASDOUT(D_CONV_TYPES, "Convolution is done with integer arithmetic.");
440 }
441 
442 template <class InputStorageType, class OutputStorageType>
445 {
446  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::FilterInt\n");
447  BIASDOUT(D_CONV_KERNEL,"Kernel is "<<_fm);
448 
449  if(!dst.SamePixelAndChannelCount(src)) {
450  dst.Release();
451  dst.Init(src.GetWidth(),src.GetHeight(),src.GetChannelCount(),
452  src.GetStorageType(),src.IsInterleaved());
453  }
454  if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_full) {
455  BIASERR("BorderHandling TBH_full not implemented");
456  return -1;
457  }
458 
459  if(_fm.IsSeparable()) {
460  if(!_tmpInt.SamePixelAndChannelCount(src)) {
461  _tmpInt.Release();
462  _tmpInt.Init(src.GetWidth(),src.GetHeight(),src.GetChannelCount(),
463  src.GetStorageType(),src.IsInterleaved());
464  }
465  ConvIntHori_(src, _tmpInt);
466  ConvIntVert_(_tmpInt, dst);
467 #ifdef BIAS_DEBUG
468  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
469  //ImageIO::Save("tmp_i_separated_after_hori",_tmpInt);
470  ImageIO::Save("tmp_i_separated_after_hori",_tmpInt);
471  }
472 #endif
473  } else ConvIntMat_(src,dst);
474 
475  unsigned int ulx,uly,lrx,lry;
476  src.GetROICorners(ulx,uly,lrx,lry);
477  if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_same) {
478  dst.GetROI()->SetCorners(ulx,uly,lrx,lry);
479  } else if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_valid) {
480  int kwidth,kheight;
481  if(_fm.IsSeparable()) {
482  kwidth = _fm.GetSepih()->Size();
483  kheight = _fm.GetSepiv()->Size();
484  } else {
485  kwidth = _fm.GetKerneli()->GetCols();
486  kheight = _fm.GetKerneli()->GetRows();
487  }
488  dst.SetROICorners(ulx+KERNCENTER(kwidth),uly+KERNCENTER(kheight),
489  lrx-KERNCENTER(kwidth),lry-KERNCENTER(kheight));
490  }
491 #ifdef BIAS_DEBUG
492  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
493  //ImageIO::Save("tmp_i_final",dst);
494  ImageIO::Save("tmp_i_final",dst);
495  }
496 #endif
497  return 0;
498 }
499 
500 template <class InputStorageType, class OutputStorageType>
503 {
504 #ifdef BIAS_DEBUG
505  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
506  Image<InputStorageType> tmp=src;
507  //ImageIO::Save("FilterFloat_Input", tmp);
508  ImageIO::Save("FilterFloat_Input", tmp);
509  }
510 #endif
511  BIASCDOUT(D_FILTERBASE_CALLSTACK,"Convolution::FilterFloat\n");
512  BIASDOUT(D_CONV_KERNEL,"Kernel is "<<_fm);
513  if(!dst.SamePixelAndChannelCount(src)) {
514  dst.Release();
515  dst.Init(src.GetWidth(),src.GetHeight(),src.GetChannelCount(),
516  dst.GetStorageType(),src.IsInterleaved());
517  }
518  if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_full) {
519  BIASERR("BorderHandling TBH_full not implemented");
520  return -1;
521  }
522 
523  if(_fm.IsSeparable()) {
524  if(!_tmpFloat.SamePixelAndChannelCount(src)) {
525  _tmpFloat.Release();
526  _tmpFloat.Init(src.GetWidth(),src.GetHeight(),src.GetChannelCount(),
528  }
529  ConvFloatHori_(src, _tmpFloat);
530 #ifdef BIAS_DEBUG
531  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
532  //ImageIO::Save("FilterFloat_Separated_AfterHorizontal",_tmpFloat);
533  ImageIO::Save("FilterFloat_Separated_AfterHorizontal",_tmpFloat);
534  }
535 #endif
536  ConvFloatVert_(_tmpFloat, dst);
537 #ifdef BIAS_DEBUG
538  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
539  //ImageIO::Save("FilterFloat_Separated_Final", dst);
540  ImageIO::Save("FilterFloat_Separated_Final", dst);
541  }
542 #endif
543  } else {
544  ConvFloatMat_(src, dst);
545 #ifdef BIAS_DEBUG
546  if (this->DebugLevelIsSet(D_WRITE_IMAGES)) {
547  //ImageIO::Save("FilterFloat_Final", dst);
548  ImageIO::Save("FilterFloat_Final", dst);
549  }
550 #endif
551  }
552 
553  unsigned int ulx,uly,lrx,lry;
554  src.GetROICorners(ulx,uly,lrx,lry);
555 
556  if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_same) {
557  dst.GetROI()->SetCorners(ulx,uly,lrx,lry);
558  } else if(this->GetBorderHandling()==Convolution<InputStorageType,OutputStorageType>::TBH_valid) {
559  int kwidth,kheight;
560  if(_fm.IsSeparable()) {
561  kwidth=_fm.GetSepfh()->Size();
562  kheight=_fm.GetSepfv()->Size();
563  } else {
564  kwidth=_fm.GetKernelf()->GetCols();
565  kheight=_fm.GetKernelf()->GetRows();
566  }
567 
568  // make sure that lr is not smaller than ul and update ROI
569  const unsigned int hwsx = KERNCENTER(kwidth);
570  ulx += hwsx;
571  if (lrx>ulx+hwsx) lrx -= hwsx; else lrx = ulx;
572  const unsigned int hwsy = KERNCENTER(kheight);
573  uly += hwsy;
574  if (lry>uly+hwsy) lry -= hwsy; else lry = uly;
575 
576  dst.GetROI()->SetCorners(ulx,uly,lrx,lry);
577  }
578  return 0;
579 }
580 
581 template <class InputStorageType, class OutputStorageType>
583 PrintKernel() const
584 {
585  if (CalculationInFloat()) { // float
586  cout << "float: ";
587  if (_fm.IsSeparable()){
588  cout << "sep horiz: "<< *_fm.GetSepfh()<<" vert: "<<*_fm.GetSepfv();
589  } else {
590  cout << "kernel: "<<*_fm.GetKernelf();
591  }
592  } else { // int
593  cout << "int: ";
594  if (_fm.IsSeparable()){
595  cout << "sep horiz: "<< *_fm.GetSepih()<<" vert: "<<*_fm.GetSepiv();
596  } else {
597  cout << "kernel: "<<*_fm.GetKerneli();
598  }
599  }
600  cout << endl;
601 }
602 
603 namespace BIAS{
604 #define FILTER_INSTANTIATION_CLASS Convolution
605 #include "Filterinst.hh"
606 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
FilterMask _fm
the kernel data used for convolution
Definition: Convolution.hh:107
int ConvFloatHori_(const Image< InputStorageType > &src, Image< CONV_FLOAT > &dst)
worker function for float separated (horizontal) convolution
generic convolution class.
Definition: Convolution.hh:66
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
Definition: ROI.cpp:287
virtual int FilterFloat(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
do the convolution using floating point calculations
virtual ~Convolution()
bool IsInterleaved() const
Definition: ImageBase.hh:471
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
decides on the image types which FilterFunction should be called
float image storage type
Definition: ImageBase.hh:118
unsigned int Size() const
length of the vector
Definition: Vector.hh:134
unsigned int GetWidth() const
Definition: ImageBase.hh:292
int ConvFloatMat_(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
worker function for float matrix convolution
void GetROICorners(unsigned int &UpperLeftX, unsigned int &UpperLeftY, unsigned int &LowerRightX, unsigned int &LowerRightY) const
access region of interest rectangle JW
Definition: ImageBase.cpp:990
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:595
int ConvFloatVert_(const Image< CONV_FLOAT > &src, Image< OutputStorageType > &dst)
worker function for float separated (vertical) convolution
unsigned int GetRows() const
Definition: Matrix.hh:202
void PrintKernel() const
prints the used filter mask, for debugging
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:362
base class for simple n-&gt;n filter implementations
Definition: FilterNToN.hh:43
unsigned int GetHeight() const
Definition: ImageBase.hh:299
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
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
unsigned int GetCols() const
Definition: Matrix.hh:204
int ConvIntMat_(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
worker function for int matrix convolution
Definition: Convolution.cpp:50
int ConvIntVert_(const Image< CONV_INT > &src, Image< OutputStorageType > &dst)
worker function for int separated (vertical) convolution
int ConvIntHori_(const Image< InputStorageType > &src, Image< CONV_INT > &dst)
worker function for int separated (horizontal) convolution
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:394
void SetZero()
reset data, all kernel to zero, separable to false
Definition: FilterMask.hh:187
int SetROICorners(unsigned int UpperLeftX, unsigned int UpperLeftY, unsigned int LowerRightX, unsigned int LowerRightY)
Definition: ImageBase.cpp:971
virtual int FilterInt(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
do the convolution using integer arithmetics and shifts
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:152