Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Median.cpp
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8  BIAS is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation; either version 2.1 of the License, or
11  (at your option) any later version.
12 
13  BIAS is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with BIAS; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
21 #include "Median.hh"
22 
23 #include "bias_config.h"
24 
25 #include <Base/Image/ImageIO.hh>
26 #include <Base/Image/ImageConvert.hh>
27 #include <MathAlgo/Median1D.hh>
28 
29 #include <algorithm>
30 
31 using namespace BIAS;
32 using namespace std;
33 
34 template<class InputStorageType, class OutputStorageType>
36  : FilterNToN<InputStorageType,OutputStorageType>()
37 {
38  _MedianSize = 2;
39  _secondSize = 2;
40  _MinValue = -1;
41 }
42 
43 template<class InputStorageType, class OutputStorageType>
46  FilterNToN<InputStorageType, OutputStorageType>(other),
47  _MedianSize(other._MedianSize)
48 {
50 }
51 
52 template<class InputStorageType, class OutputStorageType>
54 {
55 }
56 
57 int comp(const void *a, const void *b)
58 {
59  if (*(float*) a < *(float*) b)
60  return -1;
61  else if (*(float*) a > *(float*) b)
62  return 1;
63  else
64  return 0;
65 }
66 
67 template<class InputStorageType, class OutputStorageType>
70 {
71  unsigned int halfsizeX = _MedianSize;
72  unsigned int halfsizeY = _secondSize;
73 
74  if (src.GetChannelCount() != 1)
75  {
76  BIASERR("Median() not implemented for more than one channel");
77  return -1;
78  }
79 
80  //cerr << "halfsizeX " << halfsizeX << endl;
81  //cerr << "halfsizeY " << halfsizeY << endl;
82 
84  OutputStorageType **dstida = dst.GetImageDataArray();
85  const InputStorageType **srcida = src.GetImageDataArray();
86  bool identimg = false;
87  int sizeX = 2 * halfsizeX + 1;
88  int sizeY = 2 * halfsizeY + 1;
89 
90  if ((void*) src.GetImageData() != (void*) dst.GetImageData())
91  {
92  if (!src.SamePixelAndChannelCount(dst))
93  {
94  if (!dst.IsEmpty())
95  dst.Release();
96  dst.Init(src.GetWidth(), src.GetHeight(), 1);
97  dstida = dst.GetImageDataArray();
98  }
99  }
100  else
101  {
102  identimg = true;
103  tmp.Init(src.GetWidth(), src.GetHeight(), 1);
104  dstida = tmp.GetImageDataArray();
105  }
106 
107  float *z, zvalue;
108  int startx, starty, endx, endy;
109  unsigned int found;
110 
111  z = new float[sizeX * sizeY];
112  unsigned int ULx, ULy, LRx, LRy, width, height;
113  width = src.GetWidth();
114  height = src.GetHeight();
115  src.GetROI()->GetCorners(ULx, ULy, LRx, LRy);
116  for (unsigned int j = ULy; j < LRy; j++)
117  {
118 
119  for (unsigned int i = ULx; i < LRx; i++)
120  {
121  found = 0;
122  startx = int(i) - (sizeX - 1) / 2;
123  endx = int(i) + (sizeX - 1) / 2;
124  starty = int(j) - (sizeY - 1) / 2;
125  endy = int(j) + (sizeY - 1) / 2;
126  if (startx < 0)
127  startx = 0;
128  if (starty < 0)
129  starty = 0;
130  if (endx > int(width - 1))
131  endx = width - 1;
132  if (endy > int(height - 1))
133  endy = height - 1;
134  for (int y = starty; y <= endy; y++)
135  for (int x = startx; x <= endx; x++)
136  {
137  zvalue = (float) srcida[y][x];
138  if (zvalue > _MinValue)
139  {
140  z[found] = zvalue;
141  found++;
142  }
143  }
144  if (found > 0)
145  {
146  qsort(z, found, sizeof(float), comp);
147  dstida[j][i] = (OutputStorageType) z[found / 2];
148  }
149  else
150  {
151  dstida[j][i] = (OutputStorageType) 0.0;
152  }
153  }
154  }
155 
156  delete[] z;
157 
158  if (identimg)
159  dst.StealImage(tmp);
160  dst.GetROI()->SetCorners(ULx, ULy, LRx, LRy);
161  return 0;
162 }
163 
164 template<class InputStorageType, class OutputStorageType>
167 {
168  BIASERR("FilterInt makes no sense here, using general Filter interface.");
169  return Filter(src, dst);
170 }
171 
172 template<class InputStorageType, class OutputStorageType>
175 {
176  BIASERR("FilterFloat makes no sense here, using general Filter interface.");
177  return Filter(src, dst);
178 }
179 
180 template<class InputStorageType, class OutputStorageType>
183 {
184 #ifdef BIAS_DEBUG
185  if (src.GetChannelCount()!=1)
186  {
187  BIASERR("Median() not implemented for more than one channel");
188  return -1;
189  }
190 #endif
191  float z[25], zvalue;
192  unsigned found, xm, x2m, xp, x2p, ym, y2m, yp, y2p, w, maxwidth, maxheight,
193  h, x, y;
194 
195  if (!src.SamePixelAndChannelCount(dst))
196  {
197  if (!dst.IsEmpty())
198  dst.Release();
199  dst.Init(src.GetWidth(), src.GetHeight(), 1);
200  }
201 
202  OutputStorageType **dstida = dst.GetImageDataArray();
203  const InputStorageType **srcida = src.GetImageDataArray();
204 
205  memset((void*) dstida[0], 0, sizeof(OutputStorageType)
206  * dst.GetPixelCount());
207 
208  w = src.GetWidth();
209  h = src.GetHeight();
210  maxheight = h - 2;
211  maxwidth = w - 2;
212  for (y = 2; y < maxheight; y++)
213  {
214  for (x = 2; x < maxwidth; x++)
215  {
216  if ((zvalue = (float) srcida[y][x]) != 0.0)
217  {
218  z[0] = zvalue;
219  found = 1;
220  xm = x - 1;
221  x2m = x - 2;
222  xp = x + 1;
223  x2p = x + 2;
224  ym = y - 1;
225  y2m = y - 2;
226  yp = y + 1;
227  y2p = y + 2;
228  if ((zvalue = (float) srcida[y2m][x2m]) > 0.0)
229  {
230  z[found] = zvalue;
231  found++;
232  }
233  if ((zvalue = (float) srcida[y2m][xm]) > 0.0)
234  {
235  z[found] = zvalue;
236  found++;
237  }
238  if ((zvalue = (float) srcida[y2m][x]) > 0.0)
239  {
240  z[found] = zvalue;
241  found++;
242  }
243  if ((zvalue = (float) srcida[y2m][xp]) > 0.0)
244  {
245  z[found] = zvalue;
246  found++;
247  }
248  if ((zvalue = (float) srcida[y2m][x2p]) > 0.0)
249  {
250  z[found] = zvalue;
251  found++;
252  }
253  if ((zvalue = (float) srcida[ym][x2m]) > 0.0)
254  {
255  z[found] = zvalue;
256  found++;
257  }
258  if ((zvalue = (float) srcida[ym][xm]) > 0.0)
259  {
260  z[found] = zvalue;
261  found++;
262  }
263  if ((zvalue = (float) srcida[ym][x]) > 0.0)
264  {
265  z[found] = zvalue;
266  found++;
267  }
268  if ((zvalue = (float) srcida[ym][xp]) > 0.0)
269  {
270  z[found] = zvalue;
271  found++;
272  }
273  if ((zvalue = (float) srcida[ym][x2p]) > 0.0)
274  {
275  z[found] = zvalue;
276  found++;
277  }
278  if ((zvalue = (float) srcida[y][x2m]) > 0.0)
279  {
280  z[found] = zvalue;
281  found++;
282  }
283  if ((zvalue = (float) srcida[y][xm]) > 0.0)
284  {
285  z[found] = zvalue;
286  found++;
287  }
288 
289  if ((zvalue = (float) srcida[y][xp]) > 0.0)
290  {
291  z[found] = zvalue;
292  found++;
293  }
294  if ((zvalue = (float) srcida[y][x2p]) > 0.0)
295  {
296  z[found] = zvalue;
297  found++;
298  }
299  if ((zvalue = (float) srcida[yp][x2m]) > 0.0)
300  {
301  z[found] = zvalue;
302  found++;
303  }
304  if ((zvalue = (float) srcida[yp][xm]) > 0.0)
305  {
306  z[found] = zvalue;
307  found++;
308  }
309  if ((zvalue = (float) srcida[yp][x]) > 0.0)
310  {
311  z[found] = zvalue;
312  found++;
313  }
314  if ((zvalue = (float) srcida[yp][xp]) > 0.0)
315  {
316  z[found] = zvalue;
317  found++;
318  }
319  if ((zvalue = (float) srcida[yp][x2p]) > 0.0)
320  {
321  z[found] = zvalue;
322  found++;
323  }
324  if ((zvalue = (float) srcida[y2p][x2m]) > 0.0)
325  {
326  z[found] = zvalue;
327  found++;
328  }
329  if ((zvalue = (float) srcida[y2p][xm]) > 0.0)
330  {
331  z[found] = zvalue;
332  found++;
333  }
334  if ((zvalue = (float) srcida[y2p][x]) > 0.0)
335  {
336  z[found] = zvalue;
337  found++;
338  }
339  if ((zvalue = (float) srcida[y2p][xp]) > 0.0)
340  {
341  z[found] = zvalue;
342  found++;
343  }
344  if ((zvalue = (float) srcida[y2p][x2p]) > 0.0)
345  {
346  z[found] = zvalue;
347  found++;
348  }
349 
350  if (found > 4)
351  {
352  qsort(z, found, sizeof(float), comp);
353  dstida[y][x] = (OutputStorageType) (0.33 * z[(found >> 1) - 1] + 0.34 * z[found >> 1] + 0.33
354  * z[(found >> 1) + 1]);
355 
356  }
357  }
358  }
359  }
360 
361  return 0;
362 }
363 
364 template<class InputStorageType, class OutputStorageType>
368  const float& Threshold) const
369 {
370 #ifdef BIAS_DEBUG
371  if (src.GetChannelCount()!=1)
372  {
373  BIASERR("Median() not implemented for more than one channel");
374  return -1;
375  }
376 #endif
377  float z[25], zvalue;
378  unsigned found, xm, x2m, xp, x2p, ym, y2m, yp, y2p, w, maxwidth, maxheight,
379  h, x, y;
380 
381  if (!src.SamePixelAndChannelCount(dst))
382  {
383  if (!dst.IsEmpty())
384  dst.Release();
385  dst.Init(src.GetWidth(), src.GetHeight(), 1);
386  }
387 
388  OutputStorageType **dstida = dst.GetImageDataArray();
389  const InputStorageType **srcida = src.GetImageDataArray();
390 
391  memset((void*) dstida[0], 0, sizeof(OutputStorageType)
392  * dst.GetPixelCount());
393 
394  w = src.GetWidth();
395  h = src.GetHeight();
396  maxheight = h - 2;
397  maxwidth = w - 2;
398  for (y = 2; y < maxheight; y++)
399  {
400  for (x = 2; x < maxwidth; x++)
401  {
402  if ((zvalue = (float) srcida[y][x]) <= Threshold)
403  {
404  found = 0;
405  xm = x - 1;
406  x2m = x - 2;
407  xp = x + 1;
408  x2p = x + 2;
409  ym = y - 1;
410  y2m = y - 2;
411  yp = y + 1;
412  y2p = y + 2;
413  if ((zvalue = (float) srcida[y2m][x2m]) > Threshold)
414  {
415  z[found] = zvalue;
416  found++;
417  }
418  if ((zvalue = (float) srcida[y2m][xm]) > Threshold)
419  {
420  z[found] = zvalue;
421  found++;
422  }
423  if ((zvalue = (float) srcida[y2m][x]) > Threshold)
424  {
425  z[found] = zvalue;
426  found++;
427  }
428  if ((zvalue = (float) srcida[y2m][xp]) > Threshold)
429  {
430  z[found] = zvalue;
431  found++;
432  }
433  if ((zvalue = (float) srcida[y2m][x2p]) > Threshold)
434  {
435  z[found] = zvalue;
436  found++;
437  }
438  if ((zvalue = (float) srcida[ym][x2m]) > Threshold)
439  {
440  z[found] = zvalue;
441  found++;
442  }
443  if ((zvalue = (float) srcida[ym][xm]) > Threshold)
444  {
445  z[found] = zvalue;
446  found++;
447  }
448  if ((zvalue = (float) srcida[ym][x]) > Threshold)
449  {
450  z[found] = zvalue;
451  found++;
452  }
453  if ((zvalue = (float) srcida[ym][xp]) > Threshold)
454  {
455  z[found] = zvalue;
456  found++;
457  }
458  if ((zvalue = (float) srcida[ym][x2p]) > Threshold)
459  {
460  z[found] = zvalue;
461  found++;
462  }
463  if ((zvalue = (float) srcida[y][x2m]) > Threshold)
464  {
465  z[found] = zvalue;
466  found++;
467  }
468  if ((zvalue = (float) srcida[y][xm]) > Threshold)
469  {
470  z[found] = zvalue;
471  found++;
472  }
473 
474  if ((zvalue = (float) srcida[y][xp]) > Threshold)
475  {
476  z[found] = zvalue;
477  found++;
478  }
479  if ((zvalue = (float) srcida[y][x2p]) > Threshold)
480  {
481  z[found] = zvalue;
482  found++;
483  }
484  if ((zvalue = (float) srcida[yp][x2m]) > Threshold)
485  {
486  z[found] = zvalue;
487  found++;
488  }
489  if ((zvalue = (float) srcida[yp][xm]) > Threshold)
490  {
491  z[found] = zvalue;
492  found++;
493  }
494  if ((zvalue = (float) srcida[yp][x]) > Threshold)
495  {
496  z[found] = zvalue;
497  found++;
498  }
499  if ((zvalue = (float) srcida[yp][xp]) > Threshold)
500  {
501  z[found] = zvalue;
502  found++;
503  }
504  if ((zvalue = (float) srcida[yp][x2p]) > Threshold)
505  {
506  z[found] = zvalue;
507  found++;
508  }
509  if ((zvalue = (float) srcida[y2p][x2m]) > Threshold)
510  {
511  z[found] = zvalue;
512  found++;
513  }
514  if ((zvalue = (float) srcida[y2p][xm]) > Threshold)
515  {
516  z[found] = zvalue;
517  found++;
518  }
519  if ((zvalue = (float) srcida[y2p][x]) > Threshold)
520  {
521  z[found] = zvalue;
522  found++;
523  }
524  if ((zvalue = (float) srcida[y2p][xp]) > Threshold)
525  {
526  z[found] = zvalue;
527  found++;
528  }
529  if ((zvalue = (float) srcida[y2p][x2p]) > Threshold)
530  {
531  z[found] = zvalue;
532  found++;
533  }
534 
535  if (found > 4)
536  {
537 
538  qsort(z, found, sizeof(float), comp);
539  dstida[y][x] = (OutputStorageType) (0.33 * z[(found >> 1) - 1] + 0.34 * z[found >> 1] + 0.33
540  * z[(found >> 1) + 1]);
541  }
542  else
543  {
544  dstida[y][x] = (OutputStorageType) Threshold;
545  }
546  }
547  else
548  {
549  dstida[y][x] = (OutputStorageType) zvalue;
550  }
551  }
552  }
553 
554  return 0;
555 }
556 
557 template<class InputStorageType, class OutputStorageType>
560  Image<OutputStorageType>& dst, const float& Threshold) const
561 {
562 #ifdef BIAS_DEBUG
563  if (src.GetChannelCount()!=1)
564  {
565  BIASERR("Median() not implemented for more than one channel");
566  return -1;
567  }
568 #endif
569  float z[9], zvalue;
570  unsigned found, xm, xp, ym, yp, w, maxwidth, maxheight, h, x, y;
571 
572  if (!src.SamePixelAndChannelCount(dst))
573  {
574  if (!dst.IsEmpty())
575  dst.Release();
576  dst.Init(src.GetWidth(), src.GetHeight(), 1);
577  }
578 
579  OutputStorageType **dstida = dst.GetImageDataArray();
580  const InputStorageType **srcida = src.GetImageDataArray();
581  memset((void*) dstida[0], 0, sizeof(OutputStorageType)
582  * dst.GetPixelCount());
583 
584  w = src.GetWidth();
585  h = src.GetHeight();
586  maxheight = h - 1;
587  maxwidth = w - 1;
588  for (y = 1; y < maxheight; y++)
589  {
590  for (x = 1; x < maxwidth; x++)
591  {
592  if ((zvalue = (float) srcida[y][x]) <= Threshold)
593  {
594  found = 0;
595  xm = x - 1;
596  xp = x + 1;
597  ym = y - 1;
598  yp = y + 1;
599  if ((zvalue = (float) srcida[ym][xm]) > Threshold)
600  {
601  z[found] = zvalue;
602  found++;
603  }
604  if ((zvalue = (float) srcida[ym][x]) > Threshold)
605  {
606  z[found] = zvalue;
607  found++;
608  }
609  if ((zvalue = (float) srcida[ym][xp]) > Threshold)
610  {
611  z[found] = zvalue;
612  found++;
613  }
614  if ((zvalue = (float) srcida[y][xm]) > Threshold)
615  {
616  z[found] = zvalue;
617  found++;
618  }
619 
620  if ((zvalue = (float) srcida[y][xp]) > Threshold)
621  {
622  z[found] = zvalue;
623  found++;
624  }
625  if ((zvalue = (float) srcida[yp][xm]) > Threshold)
626  {
627  z[found] = zvalue;
628  found++;
629  }
630  if ((zvalue = (float) srcida[yp][x]) > Threshold)
631  {
632  z[found] = zvalue;
633  found++;
634  }
635  if ((zvalue = (float) srcida[yp][xp]) > Threshold)
636  {
637  z[found] = zvalue;
638  found++;
639  }
640 
641  if (found >= 4)
642  {
643  qsort(z, found, sizeof(float), comp);
644  // average median elements
645  dstida[y][x] = (OutputStorageType) (0.33 * z[(found >> 1) - 1] + 0.34 * z[found >> 1] + 0.33
646  * z[(found >> 1) + 1]);
647  }
648  else
649  {
650  //dstida[y][x] = (OutputStorageType)Threshold;
651  }
652  }
653  else
654  {
655  dstida[y][x] = (OutputStorageType) zvalue;
656  }
657  }
658  }
659  return 0;
660 }
661 
662 template<class InputStorageType, class OutputStorageType>
666  const float &threshold, const unsigned &min_support) const
667 {
668  if (src.GetChannelCount() != 1)
669  {
670  BIASERR("Median() not implemented for more than one channel");
671  return -1;
672  }
673 
674  float z[9], zvalue;
675  int found, xm, xp, ym, yp, x, y;
676 
677  if (!src.SamePixelAndChannelCount(dst))
678  {
679  dst.Init(src.GetWidth(), src.GetHeight(), 1);
680  }
681 
682  OutputStorageType **dstida = dst.GetImageDataArray();
683  const InputStorageType **srcida = src.GetImageDataArray();
684 
685  const int w = src.GetWidth(), h = src.GetHeight();
686  const int maxheight = h - 1, maxwidth = w - 1;
687  // #ifdef _OPENMP
688  // # pragma omp parallel for private(found, xm, xp, ym, yp, x, y, z, zvalue)
689  // #endif
690  for (y = 1; y < maxheight; y++)
691  {
692  for (x = 1; x < maxwidth; x++)
693  {
694  if ((zvalue = (float) srcida[y][x]) < threshold)
695  {
696  found = 0;
697  xm = x - 1;
698  xp = x + 1;
699  ym = y - 1;
700  yp = y + 1;
701  if ((zvalue = (float) srcida[ym][xm]) > threshold)
702  {
703  z[found] = zvalue;
704  found++;
705  }
706  if ((zvalue = (float) srcida[ym][x]) > threshold)
707  {
708  z[found] = zvalue;
709  found++;
710  }
711  if ((zvalue = (float) srcida[ym][xp]) > threshold)
712  {
713  z[found] = zvalue;
714  found++;
715  }
716  if ((zvalue = (float) srcida[y][xm]) > threshold)
717  {
718  z[found] = zvalue;
719  found++;
720  }
721 
722  if ((zvalue = (float) srcida[y][xp]) > threshold)
723  {
724  z[found] = zvalue;
725  found++;
726  }
727  if ((zvalue = (float) srcida[yp][xm]) > threshold)
728  {
729  z[found] = zvalue;
730  found++;
731  }
732  if ((zvalue = (float) srcida[yp][x]) > threshold)
733  {
734  z[found] = zvalue;
735  found++;
736  }
737  if ((zvalue = (float) srcida[yp][xp]) > threshold)
738  {
739  z[found] = zvalue;
740  found++;
741  }
742 
743  if (found >= (int) min_support)
744  {
745  qsort(z, found, sizeof(float), comp);
746  // average median elements
747  dstida[y][x] = (OutputStorageType) (z[(found >> 1)]);
748  }
749  else
750  {
751  dstida[y][x] = (OutputStorageType) zvalue;
752  }
753  }
754  else
755  {
756  dstida[y][x] = (OutputStorageType) zvalue;
757  }
758  }
759  }
760  return 0;
761 }
762 
763 template<class InputStorageType, class OutputStorageType>
766  Image<OutputStorageType>& dst, const float& threshold) const
767 {
768  if (src.GetChannelCount() != 1)
769  {
770  BIASERR("Median() not implemented for more than one channel");
771  return -1;
772  }
773 
774  float z[9], zvalue;
775  int x, y, found, minx, miny, maxx, maxy, xx, yy;
776  const int w = src.GetWidth(), h = src.GetHeight();
777 
778  if (!src.SamePixelAndChannelCount(dst))
779  {
780  if (!dst.IsEmpty())
781  dst.Release();
782  dst.Init(src.GetWidth(), src.GetHeight(), 1);
783  }
784 
785  OutputStorageType **dstida = dst.GetImageDataArray();
786  const InputStorageType **srcida = src.GetImageDataArray();
787 
788  // #ifdef _OPENMP
789  // #pragma omp parallel for private(x, y, found, minx, miny, maxx, maxy, xx, yy, z, zvalue)
790  // #endif
791 
792  for (y = 0; y < h; y++)
793  {
794  miny = (y - 1 < 0) ? (0) : (y - 1);
795  maxy = (y + 1 < h) ? (y + 1) : (h - 1);
796  for (x = 0; x < w; x++)
797  {
798  minx = (x - 1 < 0) ? (0) : (x - 1);
799  maxx = (x + 1 < w) ? (x + 1) : (w - 1);
800 
801  found = 0;
802  for (yy = miny; yy <= maxy; yy++)
803  {
804  for (xx = minx; xx <= maxx; xx++)
805  {
806  if ((zvalue = (float) srcida[yy][xx]) > threshold)
807  {
808  z[found] = zvalue;
809  found++;
810  }
811  }
812  }
813 
814  if (found == 0)
815  {
816  dstida[y][x] = (OutputStorageType) (srcida[y][x]);
817  }
818  else
819  {
820  qsort(z, found, sizeof(float), comp);
821  dstida[y][x] = (OutputStorageType) (z[found >> 1]);
822  }
823 
824  }
825  }
826  return 0;
827 }
828 
829 template<class InputStorageType, class OutputStorageType>
833  const float &Threshold) const
834 {
835  unsigned int halfsizeX = _MedianSize;
836  unsigned int halfsizeY = _secondSize;
837  int channels = src.GetChannelCount();
838  if (channels < 1)
839  {
840  BIASERR("No channels found");
841  return -1;
842  }
843  if (channels > 2)
844  {
845  BIASERR("RemoveSaltAndPepper() not implemented for more than two channels");
846  return -1;
847  }
848  if (channels > 1 && !src.IsPlanar())
849  {
850  BIASERR("Image is not planar, Median::FilterRemoveSaltAndPepper can only "
851  <<"handle planar images with more than one channel\n");
852  return -1;
853 
854  }
855 
856  // cerr << "Image has " << channels << " channel(s)" << endl;
857  // cerr << "halfsizeX " << halfsizeX << "\t halfsizeY " << halfsizeY << endl;
858 
860  OutputStorageType **dest_ida = dest.GetImageDataArray();
861  const InputStorageType **src_ida = src.GetImageDataArray();
862  bool identimg = false;
863  int sizeX = 2 * halfsizeX + 1;
864  int sizeY = 2 * halfsizeY + 1;
865  int imageheight = src.GetHeight();
866  // cerr << "sizeX " << sizeX << "\t sizeY " << sizeY << endl;
867 
868  if ((void*) src.GetImageData() != (void*) dest.GetImageData())
869  {
870  if (!src.SamePixelAndChannelCount(dest))
871  {
872  if (!dest.IsEmpty())
873  dest.Release();
874  dest.Init(src.GetWidth(), imageheight, channels,
875  src.GetStorageType(), false);
876  dest_ida = dest.GetImageDataArray();
877  }
878  dest.SetColorModel(src.GetColorModel());
879  }
880  else
881  {
882  identimg = true;
883  tmp.Init(src.GetWidth(), imageheight, channels, src.GetStorageType(),
884  false);
885  dest_ida = tmp.GetImageDataArray();
886  }
887 
888  float zvalue_ch1, zvalue_ch2, poi;
889  int startx, starty, endx, endy;
890  unsigned int found, count, output;
891  vector<float> foundvec1, foundvec2;
892  output = 0;
893  count = 0;
894  // cerr << "Width " << src.GetWidth() << "\t Height " << src.GetHeight() << endl;
895 
896  for (unsigned int j = 0; j < src.GetHeight(); j++)
897  {
898  for (unsigned int i = 0; i < src.GetWidth(); i++)
899  {
900  // set center-pixel as point of interest
901  poi = (float) src_ida[j][i];
902  if (poi > _MinValue)
903  { // pixel is valid
904  foundvec1.clear();
905  foundvec2.clear();
906  found = 0;
907 
908  startx = int(i) - (sizeX - 1) / 2;
909  endx = int(i) + (sizeX - 1) / 2;
910  starty = int(j) - (sizeY - 1) / 2;
911  endy = int(j) + (sizeY - 1) / 2;
912  if (startx < 0)
913  startx = 0;
914  if (starty < 0)
915  starty = 0;
916  if (endx > int(src.GetWidth() - 1))
917  endx = src.GetWidth() - 1;
918  if (endy > int(src.GetHeight() - 1))
919  endy = src.GetHeight() - 1;
920 
921  for (int y = starty; y <= endy; y++)
922  {
923  for (int x = startx; x <= endx; x++)
924  {
925  zvalue_ch1 = (float) src_ida[y][x];
926  if (channels == 2)
927  zvalue_ch2 = (float) src_ida[y + imageheight][x];
928  else
929  zvalue_ch2 = 0.0;
930 
931  if (zvalue_ch1 > _MinValue)
932  {
933  foundvec1.push_back(zvalue_ch1);
934  if (channels == 2)
935  foundvec2.push_back(zvalue_ch2);
936  found++;
937  output++;
938  }
939  }
940  }
941  if (found > 0)
942  {
943  Median1D<float> med(foundvec1);
944  float median_fp1 = med.GetMedian();
945  float x84_fp1 = med.GetX84();
946  float median_fp2 = 0.0f;
947  if (channels == 2) {
948  med.Compute(foundvec2);
949  median_fp2 = med.GetMedian();
950  }
951 
952  // ---- start debug output ----
953 
954  // if (output%250 == 0){
955  // cerr << "\n\nCycle: " << output << " of " << src.GetHeight()*src.GetWidth() << endl;
956  // cerr << "poi(" << startx+2 << "," << starty+2 << "): " << poi << endl;
957  // cerr << "median: " << median_fp1 << ", " << median_fp2
958  // << "\t x84: " << x84_fp1 << ", " << x84_fp2 << endl;
959  // }
960 
961  // ---- end debug output ----
962 
963  if (poi < (median_fp1 - Threshold * x84_fp1) ||
964  poi > (median_fp1 + Threshold * x84_fp1))
965  {
966  // set filtered value as output
967  count++;
968  dest_ida[starty + _secondSize][startx + _MedianSize]
969  = (OutputStorageType) median_fp1;
970  if (channels == 2)
971  dest_ida[starty + imageheight + _secondSize][startx + _MedianSize]
972  = (OutputStorageType) median_fp2;
973  }
974  else
975  { // copy output
976  dest_ida[starty + _secondSize][startx + _MedianSize]
977  = (OutputStorageType) (src_ida[starty + _secondSize][startx + _MedianSize]);
978  if (channels == 2)
979  dest_ida[starty + imageheight + _secondSize][startx + _MedianSize]
980  = (OutputStorageType) (src_ida[starty + imageheight + _secondSize][startx + _MedianSize]);
981  }
982  }
983  else
984  { // pixel is invalid, set output pixel also invalid
985  dest_ida[j][i] = (OutputStorageType) src_ida[j][i];
986  if (channels == 2)
987  dest_ida[starty + imageheight + _secondSize][startx + _MedianSize]
988  = (OutputStorageType) (src_ida[starty + imageheight + _secondSize][startx + _MedianSize]);
989  //dest_ida[j+imageheight][i] = src_ida[j+imageheight][i]; // Vision N version...
990  }
991 
992  } // if (poi >=0)
993  else
994  { // region is invalid, set output pixel also invalid
995  dest_ida[j][i] = (OutputStorageType) src_ida[j][i];
996  if (channels == 2)
997  dest_ida[j + imageheight][i] = (OutputStorageType) src_ida[j + imageheight][i];
998  }
999  } // for all x
1000  } // for all y
1001 
1002  if (identimg)
1003  {
1004  dest.StealImage(tmp);
1005  dest.SetColorModel(src.GetColorModel());
1006  }
1007 
1008  cerr << "FilterRemoveSaltAndPepper touched " << count << " of "
1009  << src.GetHeight() * src.GetWidth() << " pixels" << endl;
1010 
1011  return 0;
1012 }
1013 
1014 template<class InputStorageType, class OutputStorageType>
1016 GetBordersValid_(int &border_x, int &border_y) const
1017 {
1018  if (_secondSize > _MedianSize)
1019  {
1020  border_x = border_y = _secondSize;
1021  }
1022  else
1023  {
1024  border_x = border_y = _MedianSize;
1025  }
1026 }
1027 
1028 template<class InputStorageType, class OutputStorageType>
1031 {
1032 
1033  Image<InputStorageType> srcCopy, temp;
1034  // ImageConvert::ConvertST(src, srcCopy, dst.GetStorageType());
1035 
1036  int width = src.GetWidth();
1037  int height = src.GetHeight();
1038 
1039  /// use planar image in order to apply median filter seperately to each channel for now
1040  if (!((src.GetColorModel() == ImageBase::CM_RGB) && src.IsPlanar()))
1041  {
1042  temp = src;
1043  ImageConvert::Convert(temp, srcCopy, ImageBase::CM_RGB, true);
1044  }
1045 
1046  Image<InputStorageType> red(width, height, 1);
1047  Image<OutputStorageType> redG(width, height, 1);
1048  Image<InputStorageType> green(width, height, 1);
1049  Image<OutputStorageType> greenG(width, height, 1);
1050  Image<InputStorageType> blue(width, height, 1);
1051  Image<OutputStorageType> blueG(width, height, 1);
1052 
1053  red.GetChannel(srcCopy, 0);
1054  green.GetChannel(srcCopy, 1);
1055  blue.GetChannel(srcCopy, 2);
1056 
1057  Filter(red, redG);
1058  Filter(green, greenG);
1059  Filter(blue, blueG);
1060 
1061  dst = Image<OutputStorageType> (width, height, 3, true);
1062  for (int i = 0; i < width; i++)
1063  {
1064  for (int j = 0; j < height; j++)
1065  {
1066  dst.SetPixel(redG.PixelValue(i, j), i, j, 0);
1067  dst.SetPixel(greenG.PixelValue(i, j), i, j, 1);
1068  dst.SetPixel(blueG.PixelValue(i, j), i, j, 2);
1069  }
1070  }
1071 
1072  return 0;
1073 }
1074 
1075 template<class InputStorageType, class OutputStorageType>
1079  unsigned int px, unsigned int py,
1080  const Image<unsigned char>* ignorePixels)
1081 {
1082  unsigned int width = src.GetWidth();
1083  unsigned int height = src.GetHeight();
1084  unsigned int channels = src.GetChannelCount();
1085 
1086  if (dst.GetWidth() != width || dst.GetHeight() != height
1087  || dst.GetChannelCount() != channels)
1088  {
1089  dst.Init(width, height, channels);
1090  dst.Clear(0);
1091  }
1092 
1093  float minSum = FLT_MAX;
1094 
1095  int minX = px, minY = py;
1096 
1097  if (px >= 0 && px < width && py >= 0 && py < height)
1098  {
1099 
1100  int x1 = max(0, (int) px - _MedianSize);
1101  int y1 = max(0, (int) py - _secondSize);
1102 
1103  int x2 = min(width - 1, px + _MedianSize);
1104  int y2 = min(height - 1, py + _secondSize);
1105 
1106  for (int x = x1; x <= x2; x++)
1107  {
1108  for (int y = y1; y <= y2; y++)
1109  {
1110  unsigned char ignoreFlag = 0;
1111  if (ignorePixels != NULL)
1112  {
1113  ignoreFlag = ignorePixels->PixelValue(x, y);
1114  }
1115 
1116  if (ignoreFlag == 0)
1117  {
1118  float sum = 0;
1119 
1120  //---------------
1121  for (int tmp_x = x1; tmp_x <= x2; tmp_x++)
1122  {
1123 
1124  for (int tmp_y = y1; tmp_y <= y2; tmp_y++)
1125  {
1126 
1127  if (ignorePixels != NULL)
1128  {
1129  ignoreFlag = ignorePixels->PixelValue(tmp_x,
1130  tmp_y);
1131  }
1132 
1133  if (ignoreFlag == 0)
1134  {
1135 
1136  float tmp_sum = 0;
1137  for (unsigned short ch = 0; ch < channels; ch++)
1138  {
1139  float val1 = (float) src.PixelValue(x, y,
1140  ch);
1141  float val2 = (float) src.PixelValue(tmp_x,
1142  tmp_y, ch);
1143  float diff = pow(fabs(val1 - val2), 2);
1144 
1145  tmp_sum += diff;
1146  }
1147  sum += sqrt(tmp_sum);
1148  }
1149 
1150  }
1151  }
1152 
1153  //--------------
1154 
1155  if (sum < minSum)
1156  {
1157  minSum = sum;
1158  minX = x;
1159  minY = y;
1160  }
1161  }
1162  }
1163  }
1164 
1165  for (unsigned short ch = 0; ch < channels; ch++)
1166  {
1167  OutputStorageType val = (OutputStorageType) src.PixelValue(minX,
1168  minY, ch);
1169  dst.SetPixel(val, px, py, ch);
1170  }
1171  }
1172  else
1173  {
1174  BIASERR("pixel coordinates "<< px << " , "<<py<< " exceed image range");
1175  }
1176  return 0;
1177 }
1178 
1179 template<class InputStorageType, class OutputStorageType>
1183  const Image<unsigned char>* ignorePixels)
1184 {
1185 
1186  unsigned int width = src.GetWidth();
1187  unsigned int height = src.GetHeight();
1188  unsigned int channels = src.GetChannelCount();
1189 
1190  if (dst.GetWidth() != width || dst.GetHeight() != height
1191  || dst.GetChannelCount() != channels)
1192  {
1193  dst.Init(width, height, channels);
1194  }
1195 
1196  int x, y;
1197 #pragma omp parallel for private(x,y)
1198  for (y = 0; y < (int) height; y++)
1199  {
1200  for (x = 0; x < (int) width; x++)
1201  {
1202  unsigned char ignoreValue = 0;
1203  if (ignorePixels != NULL)
1204  {
1205  ignoreValue = ignorePixels->PixelValue(x, y);
1206  }
1207 
1208  if (ignoreValue == 0)
1209  {
1210  FilterColorImgVec(src, dst, x, y, ignorePixels);
1211  }
1212  }
1213  }
1214  return 0;
1215 }
1216 
1217 template<class InputStorageType, class OutputStorageType>
1220  Image<OutputStorageType>& dest, unsigned int numberOfThreads)
1221 {
1222  int width = source.GetWidth();
1223  int height = source.GetHeight();
1224  int size = width*height;
1225 
1226  if (dest.GetWidth() != (unsigned int) width || dest.GetHeight() != (unsigned int)height ||
1227  dest.GetChannelCount() != 1) {
1228  dest.Release();
1229  dest.Init(width,height,1);
1230  }
1231 
1232  InputStorageType* source_data = (InputStorageType*) source.GetImageData();
1233  OutputStorageType* dest_data = (OutputStorageType*) dest.GetImageData();
1234 
1235 #ifdef _OPENMP
1236  vector<InputStorageType*> sort_vector(numberOfThreads);
1237  for(unsigned int i = 0; i < sort_vector.size(); i++) {
1238  sort_vector[i] = new InputStorageType[(2*_MedianSize+1)*(2*_secondSize+1)];
1239  }
1240 #pragma omp parallel for num_threads(numberOfThreads)
1241 #else
1242 #define omp_get_thread_num() 0
1243  vector<InputStorageType*> sort_vector(numberOfThreads);
1244  sort_vector[0] = new InputStorageType[(2*_MedianSize+1)*(2*_secondSize+1)];
1245 #endif
1246  for (int i = 0; i < size; i++) {
1247 
1248  int y = i / width;
1249  int x = i - y*width;
1250 
1251  int start_x = max((int)0,x - _MedianSize);
1252  int start_y = max((int)0,y - _secondSize);
1253  int end_x = min(width -1,x + _MedianSize);
1254  int end_y = min(height - 1,y + _secondSize);
1255 
1256 
1257  int array_width = end_x - start_x + 1;
1258  int array_height = end_y - start_y + 1;
1259  int array_size = array_width* array_height;
1260 
1261  unsigned int th_num = omp_get_thread_num();
1262 
1263  InputStorageType* sort_array = sort_vector[th_num];
1264 
1265  for (int tmp_x = start_x, array_x = 0; array_x < array_width; tmp_x++, array_x++) {
1266  for (int tmp_y = start_y, array_y =0; array_y < array_height; tmp_y++, array_y++) {
1267  int index = tmp_y * width + tmp_x;
1268  int array_index = array_y * array_width + array_x;
1269  sort_array[array_index] = source_data[index];
1270  }
1271  }
1272 
1273  sort(sort_array,sort_array+array_size);
1274 
1275  int med = min(array_size / 2+1, array_size - 1);
1276 
1277  dest_data[i] = (OutputStorageType) sort_array[med];
1278 
1279 // delete [] sort_array;
1280  }
1281 
1282  for(unsigned int i = 0; i < sort_vector.size(); i++) {
1283  delete sort_vector[i];
1284  }
1285  return 0;
1286 }
1287 
1288 
1289 template<class InputStorageType, class OutputStorageType>
1292 {
1293  //
1294  if (srcs.size() != 3)
1295  {
1296  BIASERR("Number of input images not 3!");
1297  return -1;
1298  }
1299 
1300  unsigned int height = srcs[0].GetHeight();
1301  unsigned int width = srcs[0].GetWidth();
1302 
1303  for (int i = 0; i < 3; i++)
1304  {
1305  if (srcs[i].GetColorModel() != ImageBase::CM_Grey)
1306  {
1307  BIASERR("Images not grey!");
1308  return -1;
1309  }
1310  if (srcs[i].GetHeight() != height || srcs[i].GetWidth() != width)
1311  {
1312  BIASERR("Image size is not consistent!");
1313  return -1;
1314  }
1315  }
1316 
1317  dst = Image<OutputStorageType> (width, height, 1, true);
1318  //OutputStorageType** dstData = dst.GetImageDataArray();
1319 
1320  InputStorageType** imData[3];
1321  imData[0] = srcs[0].GetImageDataArray();
1322  imData[1] = srcs[1].GetImageDataArray();
1323  imData[2] = srcs[2].GetImageDataArray();
1324  //InputStorageType medValues[27];
1325  std::vector<InputStorageType> m;
1326 
1327  for (unsigned int w = 1; w < width - 1; w++)
1328  {
1329  for (unsigned int h = 1; h < height - 1; h++)
1330  {
1331  for (int i = 0; i < 3; i++)
1332  {
1333  m.push_back(imData[i][h - 1][w - 1]);
1334  m.push_back(imData[i][h - 1][w - 0]);
1335  m.push_back(imData[i][h - 1][w + 1]);
1336  m.push_back(imData[i][h - 0][w - 1]);
1337  m.push_back(imData[i][h - 0][w - 0]);
1338  m.push_back(imData[i][h - 0][w + 1]);
1339  m.push_back(imData[i][h + 1][w - 1]);
1340  m.push_back(imData[i][h + 1][w - 0]);
1341  m.push_back(imData[i][h + 1][w + 1]);
1342  }
1343 
1344  sort(m.begin(), m.end());
1345  //dstData[h][w] = (OutputStorageType)m[13];
1346  dst.SetPixel((OutputStorageType) m[13], w, h, 0);
1347  m.clear();
1348  }
1349  }
1350  return 0;
1351 }
1352 
1353 template<class InputStorageType, class OutputStorageType>
1356 {
1357  if (srcs.size() != 3)
1358  {
1359  BIASERR("Number of input images not 3!");
1360  return -1;
1361  }
1362 
1363  unsigned int height = srcs[0].GetHeight();
1364  unsigned int width = srcs[0].GetWidth();
1365 
1366  std::vector<Image<InputStorageType> > ImsRed, ImsGreen, ImsBlue;
1368 
1369  for (int i = 0; i < 3; i++)
1370  {
1371  if (srcs[i].GetHeight() != height || srcs[i].GetWidth() != width)
1372  {
1373  BIASERR("Image size is not consistent!");
1374  return -1;
1375  }
1376  // use planar image in order to apply median filter seperately to each channel for now
1377  if (!((srcs[i].GetColorModel() == ImageBase::CM_RGB)
1378  && srcs[i].IsPlanar()))
1379  {
1380  ImageConvert::Convert(srcs[i], temp, ImageBase::CM_RGB, true);
1381  }
1382  else
1383  {
1384  temp = srcs[i];
1385  }
1386  Image<InputStorageType> red(width, height, 1);
1387  Image<InputStorageType> green(width, height, 1);
1388  Image<InputStorageType> blue(width, height, 1);
1389 
1390  red.GetChannel(temp, 0);
1391  green.GetChannel(temp, 1);
1392  blue.GetChannel(temp, 2);
1393 
1394  ImsRed.push_back(red);
1395  ImsGreen.push_back(green);
1396  ImsBlue.push_back(blue);
1397  }
1398 
1399  Image<OutputStorageType> redG(width, height, 1);
1400  Image<OutputStorageType> greenG(width, height, 1);
1401  Image<OutputStorageType> blueG(width, height, 1);
1402 
1403  Filter3x3x3Grey(ImsRed, redG);
1404  Filter3x3x3Grey(ImsGreen, greenG);
1405  Filter3x3x3Grey(ImsBlue, blueG);
1406 
1407  dst = Image<OutputStorageType> (width, height, 3, true);
1408  for (unsigned int i = 0; i < width; i++)
1409  {
1410  for (unsigned int j = 0; j < height; j++)
1411  {
1412  dst.SetPixel(redG.PixelValue(i, j), i, j, 0);
1413  dst.SetPixel(greenG.PixelValue(i, j), i, j, 1);
1414  dst.SetPixel(blueG.PixelValue(i, j), i, j, 2);
1415  }
1416  }
1417 
1418  return 0;
1419 
1420 }
1421 
1422 //////////////////////////////////////////////////////////////////////////
1423 // instantiation
1424 //////////////////////////////////////////////////////////////////////////
1425 
1426 namespace BIAS{
1427 #define FILTER_INSTANTIATION_CLASS Median
1428 #include "Filterinst.hh"
1429 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
virtual function for interface definition
Definition: Median.cpp:69
DataType GetMedian() const
Return computed median.
Definition: Median1D.hh:56
int FilterOnlyBelowIgnoreBelow3x3(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const float &threshold, const unsigned &min_support=1) const
Specialized median filter for images with invalid values.
Definition: Median.cpp:664
gray values, 1 channel
Definition: ImageBase.hh:130
int _secondSize
Use this variable for non-quadratic filter sizes e.g. 3x1.
Definition: Median.hh:162
DataType GetX84() const
Return median of absolute differences to median (X84 rule).
Definition: Median1D.hh:62
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
Definition: ROI.cpp:287
void GetCorners(unsigned &UpperLeftX, unsigned &UpperLeftY, unsigned &LowerRightX, unsigned &LowerRightY) const
Return the region of interest, by saving the coordinates within the variables defined by the paramete...
Definition: ROI.hh:443
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
int Filter3x3x3Grey(std::vector< Image< InputStorageType > > &srcs, Image< OutputStorageType > &dst)
Definition: Median.cpp:1291
int FilterParallel(Image< InputStorageType > &source, Image< OutputStorageType > &dest, unsigned int numberOfThreads)
Definition: Median.cpp:1219
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
Computes the median and p-quantile of a vector.
Definition: Median1D.hh:41
virtual void GetBordersValid_(int &border_x, int &border_y) const
Definition: Median.cpp:1016
int FilterRemoveSaltAndPepper(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const float &Threshold=3.0f) const
removes &quot;salt and pepper&quot; by replacing outliers (Threshold) with median of neighbourhood.
Definition: Median.cpp:831
bool IsPlanar() const
Definition: ImageBase.hh:484
unsigned int GetWidth() const
Definition: ImageBase.hh:312
int FilterOnlyZeroIgnoreZero5x5(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const float &Threshold=0.0f) const
fill spurious gaps in depth maps compute 5x5 median at zero points, thereby ignoring zero values ...
Definition: Median.cpp:366
int FilterIgnoreZero5x5(const Image< InputStorageType > &src, Image< OutputStorageType > &dst) const
Definition: Median.cpp:182
StorageType PixelValue(const unsigned int x, const unsigned int y, const unsigned short int channel=0) const
Returns value of pixel at specific position, using specific channel as offset.
Definition: Image.hh:91
int FilterOnlyZeroIgnoreZero3x3(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const float &Threshold=0.0f) const
fill spurious gaps in depth maps compute 3x3 median at zero points, thereby ignoring zero values ...
Definition: Median.cpp:559
int GetChannel(const ImageBase &source, const unsigned int channel)
copies one specific channel from source to Image can only be called from an planar image...
Definition: ImageBase.cpp:428
void Clear(const StorageType value=0)
sets all pixels to zero/value
Definition: Image.hh:289
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:615
Implements a 2D median filter for images.
Definition: Median.hh:39
int Filter3x3x3Color(std::vector< Image< InputStorageType > > &srcs, Image< OutputStorageType > &dst)
Definition: Median.cpp:1355
int StealImage(ImageBase &source)
steals the image data array from source, after releasing the actual image data and sets source image ...
Definition: ImageBase.cpp:395
float _MinValue
Definition: Median.hh:163
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
void Compute(const std::vector< DataType > &vec)
Compute median and store sorted vector internally.
Definition: Median1D.cpp:32
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
int FilterColorImg(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Definition: Median.cpp:1030
base class for simple n-&gt;n filter implementations
Definition: FilterNToN.hh:43
unsigned int GetHeight() const
Definition: ImageBase.hh:319
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
int _MedianSize
half win size of median, 1 means 3x3
Definition: Median.hh:159
void SetPixel(const StorageType &value, const unsigned int &x, const unsigned int &y, const unsigned short int channel=0)
Set the value of a given pixel (x,y) in channel to value.
Definition: Image.hh:171
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
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
virtual ~Median()
Definition: Median.cpp:53
static int Convert(BIAS::ImageBase &source, BIAS::ImageBase &dest, enum BIAS::ImageBase::EColorModel targetColorModel, bool bPlanar=false)
main general conversion function, calls desired specialized functions, always initializes the destIma...
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
virtual int FilterInt(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Definition: Median.cpp:166
virtual int FilterFloat(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Definition: Median.cpp:174
unsigned long int GetPixelCount() const
returns number of pixels in image
Definition: ImageBase.hh:422
int FilterColorImgVec(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, unsigned int px, unsigned int py, const Image< unsigned char > *ignorePixels=NULL)
Definition: Median.cpp:1077
int FilterIgnore3x3(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const float &threshold) const
filters using only values above threshold as input
Definition: Median.cpp:765
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153