Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
GradientSobel3x3.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT 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 
26 #include "GradientSobel3x3.hh"
27 #include "FilterMask.hh"
28 
29 using namespace BIAS;
30 using namespace std;
31 
32 //////////////////////////////////////////////////////////////////////////
33 // implementation
34 //////////////////////////////////////////////////////////////////////////
35 template <class InputStorageType, class OutputStorageType> void
38 {
39  // this is a filtermask in the sense of convolution
40  // it is reflected at its symmetry center before being "dropped"
41  // onto the image !
42  Vector<FM_INT> h(3), v(3);
43  h[0] = 1;
44  h[1] = 0;
45  h[2] = -1;
46  v[0] = v[2] = 1;
47  v[1] = 2;
48 
49  FilterMask f(h, v, 1, 2);
50  //FilterMask f(h, v, 2, 2);
52  _Conv.SetKernel(f);
53 }
54 
55 template <class InputStorageType, class OutputStorageType>
58  : FilterNTo2N<InputStorageType, OutputStorageType>()
59 {
60  InitKernel_();
61  _fwork = _fwork2 = NULL;
62  _iwork = _iwork2 = NULL;
64 }
65 
66 template <class InputStorageType, class OutputStorageType>
69 {
70  InitKernel_();
71  _fwork = _fwork2 = NULL;
72  _iwork = _iwork2 = NULL;
73  _InternalMemWidth = _InternalMemHeight = 0;
74 }
75 
76 template <class InputStorageType, class OutputStorageType>
79 {
80  _DeleteInternalMem();
81 }
82 
83 
84 template <class InputStorageType, class OutputStorageType>
87 {
88  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Filter(src, dst)\n");
90  int res=Filter(src, grad, gy);
91  grad.AppendChannel(gy);
92  return res;
93 }
94 
95 template <class InputStorageType, class OutputStorageType>
99 {
100  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Filter(src, gx, gy)\n");
101  int res=0;
102  if (!gx.SamePixelAndChannelCount(src)){
103  gx.Release();
104  gx.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
105  }
106  if (!gy.SamePixelAndChannelCount(src)){
107  gy.Release();
108  gy.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
109  }
110 
111  if (src.GetChannelCount()==1) {
112  if (_InternalMemWidth < (int)src.GetWidth() ||
113  _InternalMemHeight < (int)src.GetHeight() ) _DeleteInternalMem();
114  if (_Conv.CalculationInFloat()){
115  if (_fwork == NULL) _AllocInternalMem(src.GetWidth(), src.GetHeight());
116  switch (this->_FilterBorderHandling){
118  res = Sobel3x3GreyValidFloat_(src, gx, gy);
119  break;
121  res = Sobel3x3GreySameFloat_(src, gx, gy);
122  break;
123  default:
124  BIASERR("unfinished");
125  res = -1;
126  break;
127  }
128  } else {
129  if (_iwork == NULL) _AllocInternalMem(src.GetWidth(), src.GetHeight());
130  res = Sobel3x3GreyValidInt_(src, gx, gy);
131  }
132  } else {
133  // grest
134  BIASERR("not for multiple channel images");
135  return -5;
136 // if (_Conv.Filter(src, gx)!=0) {
137 // BIASERR("Error in gradient x computation...");
138 // return -1;
139 // }
140 // FilterMask f;
141 // _Conv.GetKernel(f);
142 // f.Transpose();
143 // _Conv.SetKernel(f);
144 // res = _Conv.Filter(src, gy);
145 // // re-set original kernel
146 // f.Transpose();
147 // _Conv.SetKernel(f);
148  }
149  gx.SetROI(*src.GetROI());
150  gy.SetROI(*src.GetROI());
151  ShrinkROI_(gx.GetROI());
152  ShrinkROI_(gy.GetROI());
153 
154  return res;
155 }
156 
157 template <class InputStorageType, class OutputStorageType>
161 {
162  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Filter(src, gx, gy, abs)\n");
163  if (!src.SamePixelAndChannelCount(absg)){
164  if (!absg.IsEmpty()) absg.Release();
165  absg.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
166  }
167 
168  int res, absres=0;
169  res = Filter(src, gx, gy);
170 
171  absres = this->VecLen(gx, gy, absg);
172  absg.SetROI(*src.GetROI());
173  ShrinkROI_(absg.GetROI());
174 
175  return (res==0 && absres==0)?0:-1;
176 }
177 
178 
179 
180 
181 template <class InputStorageType, class OutputStorageType>
186 {
187  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Sobel3x3GreyValidFloat_\n");
188  const InputStorageType *im=src.GetImageData();
189  OutputStorageType *gx=gWE.GetImageData();
190  OutputStorageType *gy=gNS.GetImageData();
191  const int width=(int)src.GetWidth();
192  const int nwidth = - width;
193  const int height=(int)src.GetHeight();
194 
195 #ifdef BIAS_DEBUG
196  BIASASSERT(src.GetChannelCount()==1);
197  BIASASSERT(src.SamePixelAndChannelCount(gWE));
198  BIASASSERT(src.SamePixelAndChannelCount(gNS));
199  BIASASSERT(gx!=gy);
200  BIASASSERT(_Conv.CalculationInFloat());
201 #endif
202 
203  if (width>this->_InternalMemWidth || height>this->_InternalMemHeight){
204  this->_DeleteInternalMem();
205  this->_AllocInternalMem(width, height);
206  }
207 
208  int minx, miny, maxx, maxy;
209  src.GetROI()->GetCorners(minx, miny, maxx, maxy);
210  gWE.GetROI()->SetCorners(minx+1, miny+1, maxx-1, maxy-1);
211  gNS.GetROI()->SetCorners(minx+1, miny+1, maxx-1, maxy-1);
212 
213  const InputStorageType *end, *p, *lend;
214  CONV_FLOAT *ph, *pv;
215  int offset;
216  OutputStorageType *pgx, *pgy, *end2, *lend2;
217  CONV_FLOAT tmp, tmpx, tmpy;
218  int roiw=maxx-minx-1;
219  int step=width-maxx+minx;
220 
221  // separated sobel 3x3 for gx and gy
222 
223  // first line
224  offset=minx+miny*width;
225  p=im+1+offset;
226  ph=this->_fwork[0]+1+offset;
227  pv=this->_fwork2[0]+offset+width;
228  lend=p+roiw-1;
229  while (p<lend){
230  tmp = (CONV_FLOAT(*p))*2.0f;
231  *ph++ = CONV_FLOAT(p[-1]) + tmp + CONV_FLOAT(p[1]);
232  p++;
233  }
234  p+=step+1;
235  ph+=step+1;
236  lend+=width;
237  end=im+maxx-1+(maxy-2)*width;
238  while (p<end){
239  tmp = (CONV_FLOAT(*p))*2.0f;
240  *pv++ = CONV_FLOAT(p[nwidth]) + tmp + CONV_FLOAT(p[width]);
241  ph++;
242  p++;
243  while (p<lend){
244  tmp = (CONV_FLOAT(*p))*2.0f;
245  *ph++ = CONV_FLOAT(p[-1]) + tmp + CONV_FLOAT(p[1]);
246  *pv++ = CONV_FLOAT(p[nwidth]) + tmp + CONV_FLOAT(p[width]);
247  p++;
248  }
249  tmp = (CONV_FLOAT(*p))*2.0f;
250  *pv++ = CONV_FLOAT(p[nwidth]) + tmp + CONV_FLOAT(p[width]);
251  ph++;
252  p++;
253  lend+=width;
254  p+=step;
255  ph+=step;
256  pv+=step;
257  }
258  p++; ph++;
259  // last line
260  while (p<lend){
261  tmp = (CONV_FLOAT(*p))*2.0f;
262  *ph++ = CONV_FLOAT(p[-1]) + tmp + CONV_FLOAT(p[1]);
263  p++;
264  }
265 
266  // now second run from temporary to gradients
267 
268  offset=minx+1+(miny+1)*width;
269  ph=this->_fwork[0]+offset;
270  pv=this->_fwork2[0]+offset;
271  pgx=gx+offset;
272  pgy=gy+offset;
273  step+=2;
274  end2=gx+maxx+width*(maxy-2)-1;
275  lend2=gx+maxx+width*(miny+1)-1;
276  while (pgx<end2){
277  while (pgx<lend2){
278  tmpx = (pv[1] - pv[-1])/8.0f;
279  tmpy = (ph[width] - ph[nwidth])/8.0f;
280  *pgx++ = (OutputStorageType)tmpx;
281  *pgy++ = (OutputStorageType)tmpy;
282  pv++;
283  ph++;
284  }
285  pv+=step;
286  ph+=step;
287  pgx+=step;
288  pgy+=step;
289  lend2+=width;
290  }
291  return 0;
292 }
293 
294 template <class InputStorageType, class OutputStorageType>
299 {
300  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Sobel3x3GreySameFloat_\n");
301  int res=0;
302  res = Sobel3x3GreyValidFloat_(src, gWE, gNS);
303 
304  int minx, miny, maxx, maxy;
305  src.GetROI()->GetCorners(minx, miny, maxx, maxy);
306  register int x, y, xp, xm, yp, ym;
307 
308  const InputStorageType **srcida=src.GetImageDataArray();
309  OutputStorageType **gweida=gWE.GetImageDataArray();
310  OutputStorageType **gnsida=gNS.GetImageDataArray();
311 
312  // upper left pixel
313  x = minx;
314  y = miny;
315  xp = x+1;
316  xm = x;
317  yp = y+1;
318  ym = y;
319  gweida[y][x] =
320  OutputStorageType((float(srcida[ym][xp])-float(srcida[ym][xm])+
321  2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
322  float(srcida[yp][xp])-float(srcida[yp][xm]))/8.0);
323  gnsida[y][x] =
324  OutputStorageType((float(srcida[yp][xm])-float(srcida[ym][xm])+
325  2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
326  float(srcida[yp][xp])-float(srcida[ym][xp]))/8.0);
327 
328  // upper right pixel
329  x = maxx-1;
330  y = miny;
331  xp = x;
332  xm = x-1;
333  yp = y+1;
334  ym = y;
335  gweida[y][x] =
336  OutputStorageType((float(srcida[ym][xp])-float(srcida[ym][xm])+
337  2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
338  float(srcida[yp][xp])-float(srcida[yp][xm]))/8.0);
339  gnsida[y][x] =
340  OutputStorageType((float(srcida[yp][xm])-float(srcida[ym][xm])+
341  2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
342  float(srcida[yp][xp])-float(srcida[ym][xp]))/8.0);
343 
344  // lower right pixel
345  x = maxx-1;
346  y = maxy-1;
347  xp = x;
348  xm = x-1;
349  yp = y;
350  ym = y-1;
351  gweida[y][x] =
352  OutputStorageType((float(srcida[ym][xp])-float(srcida[ym][xm])+
353  2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
354  float(srcida[yp][xp])-float(srcida[yp][xm]))/8.0);
355  gnsida[y][x] =
356  OutputStorageType((float(srcida[yp][xm])-float(srcida[ym][xm])+
357  2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
358  float(srcida[yp][xp])-float(srcida[ym][xp]))/8.0);
359 
360  // lower left pixel
361  x = minx;
362  y = maxy-1;
363  xp = x+1;
364  xm = x;
365  yp = y;
366  ym = y-1;
367  gweida[y][x] =
368  OutputStorageType((float(srcida[ym][xp])-float(srcida[ym][xm])+
369  2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
370  float(srcida[yp][xp])-float(srcida[yp][xm]))/8.0);
371  gnsida[y][x] =
372  OutputStorageType((float(srcida[yp][xm])-float(srcida[ym][xm])+
373  2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
374  float(srcida[yp][xp])-float(srcida[ym][xp]))/8.0);
375 
376  // upper row
377  y = miny;
378  yp = y+1;
379  for (x=minx+1; x<maxx-1; x++){
380  xp = x+1;
381  xm = x-1;
382  gweida[y][x] =
383  OutputStorageType((2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
384  float(srcida[yp][xp])-float(srcida[yp][xm]))/6.0);
385  gnsida[y][x] =
386  OutputStorageType((2.0*(float(srcida[yp][x])-float(srcida[y][x]))+
387  float(srcida[yp][xp])+float(srcida[yp][xm])-
388  float(srcida[y][xp])-float(srcida[y][xm]))/8.0);
389  }
390  // lower row
391  y=maxy-1;
392  ym = y-1;
393  for (x=minx+1; x<maxx-1; x++){
394  xp = x+1;
395  xm = x-1;
396  gweida[y][x] =
397  OutputStorageType((2.0*(float(srcida[y][xp])-float(srcida[y][xm]))+
398  float(srcida[ym][xp])-float(srcida[ym][xm]))/6.0);
399  gnsida[y][x] =
400  OutputStorageType((2.0*(float(srcida[y][x])-float(srcida[ym][x]))-
401  float(srcida[ym][xp])-float(srcida[ym][xm])+
402  float(srcida[y][xp])+float(srcida[y][xm]))/8.0);
403  }
404  // left column
405  x = minx;
406  xp = x+1;
407  for (y=miny+1; y<maxy-1; y++){
408  yp = y+1;
409  ym = y-1;
410  gweida[y][x] =
411  OutputStorageType((2.0*(float(srcida[y][xp])-float(srcida[y][x]))+
412  float(srcida[ym][xp])+float(srcida[yp][xp])-
413  float(srcida[ym][x])-float(srcida[yp][x]))/8.0);
414  gnsida[y][x] =
415  OutputStorageType((2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
416  float(srcida[yp][xp])-float(srcida[ym][xp]))/6.0);
417  }
418 
419  // right column
420  x = maxx-1;
421  xm = x-1;
422  for (y=miny+1; y<maxy-1; y++){
423  yp = y+1;
424  ym = y-1;
425  gweida[y][x] =
426  OutputStorageType((2.0*(float(srcida[y][x])-float(srcida[y][xm]))-
427  float(srcida[ym][xm])-float(srcida[yp][xm])+
428  float(srcida[ym][x])+float(srcida[yp][x]))/8.0);
429  gnsida[y][x] =
430  OutputStorageType((2.0*(float(srcida[yp][x])-float(srcida[ym][x]))+
431  float(srcida[yp][xm])-float(srcida[ym][xm]))/6.0);
432  }
433 
434  gWE.GetROI()->SetCorners(minx, miny, maxx, maxy);
435  gNS.GetROI()->SetCorners(minx, miny, maxx, maxy);
436 
437  return res;
438 }
439 
440 template <class InputStorageType, class OutputStorageType>
445 {
446  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientSobel3x3::Sobel3x3GreyValidInt_\n");
447  const InputStorageType *im=src.GetImageData();
448  OutputStorageType *gx=gWE.GetImageData();
449  OutputStorageType *gy=gNS.GetImageData();
450  const int width=(int)src.GetWidth();
451  const int nwidth = - width;
452  const int height=(int)src.GetHeight();
453 
454 #ifdef BIAS_DEBUG
455  BIASASSERT(src.GetChannelCount()==1);
456  BIASASSERT(src.SamePixelAndChannelCount(gWE));
457  BIASASSERT(src.SamePixelAndChannelCount(gNS));
458  BIASASSERT(gx!=gy);
459  BIASASSERT(!_Conv.CalculationInFloat());
460 #endif
461 
462  if (width>this->_InternalMemWidth || height>this->_InternalMemHeight){
463  this->_DeleteInternalMem();
464  this->_AllocInternalMem(width, height);
465  }
466 
467  int minx, miny, maxx, maxy;
468  src.GetROI()->GetCorners(minx, miny, maxx, maxy);
469  gWE.GetROI()->SetCorners(minx+1, miny+1, maxx-1, maxy-1);
470  gNS.GetROI()->SetCorners(minx+1, miny+1, maxx-1, maxy-1);
471 
472  const InputStorageType *end, *p, *lend;
473  CONV_INT *ph, *pv;
474  int offset;
475  OutputStorageType *pgx, *pgy, *end2, *lend2;
476  CONV_INT tmp, tmpx, tmpy;
477  int roiw=maxx-minx-1;
478  int step=width-maxx+minx;
479 
480  // separated sobel 3x3 for gx and gy
481 
482  // first line
483  offset=minx+miny*width;
484  p=im+1+offset;
485  ph=this->_iwork[0]+1+offset;
486  pv=this->_iwork2[0]+offset+width;
487  lend=p+roiw-1;
488  while (p<lend){
489  tmp = (CONV_INT(*p))<<1;
490  *ph++ = CONV_INT(p[-1]) + tmp + CONV_INT(p[1]);
491  p++;
492  }
493  p+=step+1;
494  ph+=step+1;
495  lend+=width;
496  end=im+maxx-1+(maxy-2)*width;
497  while (p<end){
498  tmp = (CONV_INT(*p))<<1;
499  *pv++ = CONV_INT(p[nwidth]) + tmp + CONV_INT(p[width]);
500  ph++;
501  p++;
502  while (p<lend){
503  tmp = (CONV_INT(*p))<<1;
504  *ph++ = CONV_INT(p[-1]) + tmp + CONV_INT(p[1]);
505  *pv++ = CONV_INT(p[nwidth]) + tmp + CONV_INT(p[width]);
506  p++;
507  }
508  tmp = (CONV_INT(*p))<<1;
509  *pv++ = CONV_INT(p[nwidth]) + tmp + CONV_INT(p[width]);
510  ph++;
511  p++;
512  lend+=width;
513  p+=step;
514  ph+=step;
515  pv+=step;
516  }
517  p++; ph++;
518  // last line
519  while (p<lend){
520  tmp = (CONV_INT(*p))<<1;
521  *ph++ = CONV_INT(p[-1]) + tmp + CONV_INT(p[1]);
522  p++;
523  }
524 
525  // now second run from temporary to gradients
526 
527  offset=minx+1+(miny+1)*width;
528  ph=this->_iwork[0]+offset;
529  pv=this->_iwork2[0]+offset;
530  pgx=gx+offset;
531  pgy=gy+offset;
532  step+=2;
533  end2=gx+maxx+width*(maxy-2)-1;
534  lend2=gx+maxx+width*(miny+1)-1;
535  while (pgx<end2){
536  while (pgx<lend2){
537  tmpx = (pv[1] - pv[-1])>>3; // /8.0;
538  tmpy = (ph[width] - ph[nwidth])>>3; // /8.0;
539  *pgx++ = (OutputStorageType)tmpx;
540  *pgy++ = (OutputStorageType)tmpy;
541  pv++;
542  ph++;
543  }
544  pv+=step;
545  ph+=step;
546  pgx+=step;
547  pgy+=step;
548  lend2+=width;
549  }
550 
551  return 0;
552 }
553 
554 template <class InputStorageType, class OutputStorageType>
557 {
558  if (this->_fwork!=NULL) {
559  delete[] this->_fwork[0]; this->_fwork[0]=NULL;
560  delete[] this->_fwork; this->_fwork=NULL;
561  }
562  if (_fwork2!=NULL) {
563  delete[] _fwork2[0]; _fwork2[0]=NULL;
564  delete[] _fwork2; _fwork2=NULL;
565  }
566  if (this->_iwork!=NULL) {
567  delete[] this->_iwork[0]; this->_iwork[0]=NULL;
568  delete[] this->_iwork; this->_iwork=NULL;
569  }
570  if (_iwork2!=NULL) {
571  delete[] _iwork2[0]; _iwork2[0]=NULL;
572  delete[] _iwork2; _iwork2=NULL;
573  }
574  this->_InternalMemWidth=this->_InternalMemHeight=0;
575 }
576 
577 template <class InputStorageType, class OutputStorageType>
579 _AllocInternalMem(const int width, const int height)
580 {
581 #ifdef BIAS_DEBUG
582  if ((this->_fwork!=NULL) || (_fwork2!=NULL) ||
583  (this->_iwork!=NULL) || (_iwork2!=NULL)){
584  BIASERR("memory leak, reallocating without deleting!");
585  BIASABORT;
586  }
587 #endif
588  int size=width*height;
589 
590  if (_Conv.CalculationInFloat()){
591  this->_fwork = new CONV_FLOAT*[height];
592  this->_fwork[0] = new CONV_FLOAT[size];
593  _fwork2 = new CONV_FLOAT*[height];
594  _fwork2[0] = new CONV_FLOAT[size];
595  for (int i=1; i<height; i++) {
596  this->_fwork[i]=this->_fwork[i-1]+width;
597  _fwork2[i]=_fwork2[i-1]+width;
598  }
599  } else {
600  this->_iwork = new CONV_INT*[height];
601  this->_iwork[0] = new CONV_INT[size];
602  _iwork2 = new CONV_INT*[height];
603  _iwork2[0] = new CONV_INT[size];
604  for (int i=1; i<height; i++) {
605  this->_iwork[i]=this->_iwork[i-1]+width;
606  _iwork2[i]=_iwork2[i-1]+width;
607  }
608  }
609 
610  this->_InternalMemWidth=width;
611  this->_InternalMemHeight=height;
612 }
613 
614 template <class InputStorageType, class OutputStorageType>
616 GetBordersValid_(int &border_x, int &border_y) const
617 {
618  border_x = border_y = 1;
619 }
620 
621 template <class InputStorageType, class OutputStorageType>
623 ShrinkROI_(ROI *roi) const
624 {
625  BIASASSERT(roi);
626  switch (roi->GetROIType()){
627  case ROI_Corners:
628  {
629  unsigned UpperLeftX, UpperLeftY, LowerRightX, LowerRightY;
630  roi->GetCorners(UpperLeftX, UpperLeftY, LowerRightX, LowerRightY);
631  UpperLeftX++;
632  UpperLeftY++;
633  if (LowerRightX>0){
634  LowerRightX--;
635  } else {
636  BIASERR("should not happen"); BIASABORT;
637  }
638  if (LowerRightY>0){
639  LowerRightY--;
640  } else {
641  BIASERR("should not happen"); BIASABORT;
642  }
643  roi->SetCorners(UpperLeftX, UpperLeftY, LowerRightX, LowerRightY);
644  }
645  break;
646  case ROI_Rows:
647  {
648  vector<unsigned> start, end;
649  if (!roi->GetRows(start, end)){
650  BIASERR("should not happen"); BIASABORT;
651  }
652  BIASASSERT(start.size()==end.size());
653  for (unsigned y=0; y<start.size(); y++){
654  if (start[y]!=0 || end[y]!=0){
655  start[y]++;
656  if (end[y]>0){
657  end[y]--;
658  } else {
659  BIASERR("should not happen"); BIASABORT;
660  }
661  }
662  }
663  }
664  break;
665  case ROI_Mask:
666  case ROI_Points:
667  default:
668  BIASERR("GradientSobel3x3::ShrinkROI_() unhandled ROI type: "
669  <<roi->GetROIType()<<endl);
670  break;
671  }
672 }
673 
674 
675 //////////////////////////////////////////////////////////////////////////
676 // instantiation
677 //////////////////////////////////////////////////////////////////////////
678 namespace BIAS{
679 #define FILTER_INSTANTIATION_CLASS GradientSobel3x3
680 #define FILTER_INSTANTIATION_NO_UNSIGNED_OUTPUT
681 #include "Filterinst.hh"
682 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
class for handling different region of interest (ROI) representations...
Definition: ROI.hh:118
enum ERoiType GetROIType() const
is the mask image valid?
Definition: ROI.hh:303
void ShrinkROI_(ROI *roi) const
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
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
void InitKernel_()
sets the sobel kernel for the convolution object
int AppendChannel(Image< StorageType > &img)
Definition: Image.cpp:1457
base class for simple n-&gt;2n filter implementations
Definition: FilterNTo2N.hh:44
void CreateFloatFilter()
create the float filter from the int filter
Definition: FilterMask.cpp:91
gradient calculation with sobel 3 by 3 masks
unsigned int GetWidth() const
Definition: ImageBase.hh:312
int Sobel3x3GreyValidInt_(const Image< InputStorageType > &src, Image< OutputStorageType > &gWE, Image< OutputStorageType > &gNS)
uses CONV_INT for calculation
int Sobel3x3GreyValidFloat_(const Image< InputStorageType > &src, Image< OutputStorageType > &gWE, Image< OutputStorageType > &gNS)
uses CONV_FLOAT for calculation
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:615
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
bool GetRows(std::vector< unsigned > &start, std::vector< unsigned > &end) const
Horizontal start and end position per image row, the length of the vectors always corresponds to the ...
Definition: ROI.hh:261
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 SetROI(unsigned int UpperLeftX, unsigned int UpperLeftY, unsigned int LowerRightX, unsigned int LowerRightY)
deprecated, use SetROICorners()
Definition: ImageBase.cpp:1033
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
void _AllocInternalMem(const int width, const int height)
deletes _work1 and _work2 and sets _InternalMemSize
virtual void GetBordersValid_(int &border_x, int &border_y) const
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &grad)
returns a 2 channel image containing gx and gy
int Sobel3x3GreySameFloat_(const Image< InputStorageType > &src, Image< OutputStorageType > &gWE, Image< OutputStorageType > &gNS)
Repeats the border pixel infinitly in direction perpendicular to the border to achieve destination im...
A filter mask (or a kernel) used for convolution.
Definition: FilterMask.hh:61
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153