25 #include "GaussThreshold.hh"
26 #include <Base/Image/ImageConvert.hh>
27 #include <Base/Image/ImageIO.hh>
38 template <
class InputStorageType,
class OutputStorageType>
41 :
Convolution<InputStorageType, OutputStorageType>()
51 template <
class InputStorageType,
class OutputStorageType>
54 : _GaussSigma(other._GaussSigma),
55 _GaussRatio(other._GaussRatio),
56 _LastSigma(other._LastSigma),
57 _LastRatio(other._LastRatio)
62 template <
class StorageType,
class KernelType>
65 if (_GaussIO!=NULL)
delete _GaussIO;
66 if (_GaussOO!=NULL)
delete _GaussOO;
71 template <
class InputStorageType,
class OutputStorageType>
75 BIASCDOUT(D_FILTERBASE_CALLSTACK,
"Gauss::Filter\n");
76 if ((_GaussSigma != _LastSigma)||(_GaussRatio != _LastRatio))
77 _CalculateKernels(_GaussSigma, _GaussRatio);
82 if ((src.
GetChannelCount()==1) && (this->GetBorderHandling() == TBH_valid))
83 return Filter7x7GreyIgnoreBelowThreshold(src, dst, _Threshold);
84 BIASERR(
"Not yet implemented");
92 template <
class InputStorageType,
class OutputStorageType>
96 const int hws = (int)(floor(sqrt(-2.0*Sigma*Sigma*log(Ratio))));
97 const int size = (hws<<1)+1;
100 BIASCDOUT(D_CONV_KERNEL,
"Sigma = "<<Sigma<<
"\tRatio = "<<Ratio<<endl);
101 BIASCDOUT(D_CONV_KERNEL,
"size = "<<size<<
"\thws = "<<hws<<endl);
108 double fac=1.0/(2.0*Sigma*Sigma);
111 for (i=0; i<=hws; i++){
114 g = expf((
float)(-(
double)(i*i)*fac));
115 V[ip] = V[im] = H[im] = H[ip] = (FM_FLOAT)g;
120 BIASCDOUT(D_CONV_KERNEL,
"sum = "<<sum<<endl);
124 BIASCDOUT(D_CONV_KERNEL,
"sum = "<<sum<<endl);
125 for (i=0; i<=hws; i++){
128 H[ip] = H[im] = V[ip] = V[im] = V[im] * (FM_FLOAT)sum;
129 BIASCDOUT(D_CONV_KERNEL, H[im]<<
" "<<endl);
134 int thebits = _fm.ComputeIntPrecisionBits(
sizeof(InputStorageType)*8,
135 sizeof(CONV_INT)*8-1);
136 _fm.CreateIntFilter(thebits,thebits,thebits);
142 if (this->DebugLevelIsSet(D_CONV_KERNEL)){
144 for (i=-hws; i<=hws; i++){
146 BIASCDOUT(D_CONV_KERNEL, H[i+hws]<<
" ");
148 BIASCDOUT(D_CONV_KERNEL,
" sum = "<<sum<<endl);
154 fprintf(stdout,
"gauss: \n");
155 for (i=-hws; i<=hws; i++){
156 fprintf(stdout,
"%f ",HVec[i+hws]);
158 fprintf(stdout,
"\n");
162 template <
class InputStorageType,
class OutputStorageType>
168 BIASCDOUT(D_FILTERBASE_CALLSTACK,
"GaussThreshold::Filter7x7\n");
169 SetHalfWinSize(3,
false);
170 if ((_GaussSigma != _LastSigma)||(_GaussRatio != _LastRatio))
171 _CalculateKernels(_GaussSigma, _GaussRatio);
173 const FM_FLOAT h0 = (
const FM_FLOAT)((*_fm.GetSepfh())[3]);
174 const FM_FLOAT h1 = (
const FM_FLOAT)((*_fm.GetSepfh())[2]);
175 const FM_FLOAT h2 = (
const FM_FLOAT)((*_fm.GetSepfh())[1]);
176 const FM_FLOAT h3 = (
const FM_FLOAT)((*_fm.GetSepfh())[0]);
177 const FM_FLOAT v0 = (
const FM_FLOAT)((*_fm.GetSepfv())[3]);
178 const FM_FLOAT v1 = (
const FM_FLOAT)((*_fm.GetSepfv())[2]);
179 const FM_FLOAT v2 = (
const FM_FLOAT)((*_fm.GetSepfv())[1]);
180 const FM_FLOAT v3 = (
const FM_FLOAT)((*_fm.GetSepfv())[0]);
184 BIASERR(
"image with multiple channels. stopping.");
192 if(!_tmpFloat.SamePixelAndChannelCount(src)) {
193 if (!_tmpFloat.IsEmpty()) _tmpFloat.Release();
200 CONV_FLOAT* pD = _tmpFloat.GetImageData();
202 *pD++ = CONV_FLOAT(thresh);
204 *pD++ = CONV_FLOAT(thresh);
206 *pD++ = CONV_FLOAT(thresh);
209 const int width2 = 2*width, width3=3*width;
210 const InputStorageType* pEndH = src.
GetImageData() + width*height-3;
213 register CONV_FLOAT normalization = 0;
214 register CONV_FLOAT accumulator = 0;
217 accumulator += h3*CONV_FLOAT(pS[-3]);
221 accumulator += h2*CONV_FLOAT(pS[-2]);
225 accumulator += h1*CONV_FLOAT(pS[-1]);
229 accumulator += h0*CONV_FLOAT(pS[0]);
233 accumulator += h1*CONV_FLOAT(pS[1]);
238 accumulator += h2*CONV_FLOAT(pS[2]);
242 accumulator += h3*CONV_FLOAT(pS[3]);
244 if (normalization>MIN_NORM)
245 *pD++ = CONV_FLOAT(accumulator / normalization);
247 *pD++ = CONV_FLOAT(thresh);
250 *pD++ = CONV_FLOAT(thresh);pS++;
251 *pD++ = CONV_FLOAT(thresh);pS++;
252 *pD = CONV_FLOAT(thresh);pS++;
254 const CONV_FLOAT cfthresh = CONV_FLOAT(thresh);
257 const CONV_FLOAT* pEndV = _tmpFloat.GetImageData() + width*(height-3);
258 CONV_FLOAT* pI = _tmpFloat.GetImageData();
260 const CONV_FLOAT* pEndFirst3 = _tmpFloat.GetImageData() + 3*width;
261 const CONV_FLOAT* pEndLast3 = _tmpFloat.GetImageData() + width*height;
263 while (pI<pEndFirst3) {
264 *pO++ = OutputStorageType(thresh);
270 register CONV_FLOAT normalization = 0;
271 register CONV_FLOAT accumulator = 0;
273 if (pI[-width3]>cfthresh) {
275 accumulator += v3*CONV_FLOAT(pI[-width3]);
277 if (pI[-width2]>cfthresh) {
279 accumulator += v2*CONV_FLOAT(pI[-width2]);
281 if (pI[-width]>cfthresh) {
283 accumulator += v1*CONV_FLOAT(pI[-width]);
285 if (pI[0]>cfthresh) {
287 accumulator += v0*CONV_FLOAT(pI[0]);
289 if (pI[width]>cfthresh) {
291 accumulator += v1*CONV_FLOAT(pI[width]);
294 if (pI[width2]>cfthresh) {
296 accumulator += v2*CONV_FLOAT(pI[width2]);
298 if (pI[width3]>cfthresh) {
300 accumulator += v3*CONV_FLOAT(pI[width3]);
303 if (normalization>MIN_NORM)
304 *pO++ = OutputStorageType(accumulator / normalization);
306 *pO++ = OutputStorageType(thresh);
310 while (pI<pEndLast3) {
311 *pO++ = OutputStorageType(thresh);
316 unsigned minx, miny, maxx, maxy;
324 if (minx>maxx) minx = maxx = (minx+maxx)/2;
325 if (miny>maxy) miny = maxy = (miny+maxy)/2;
332 template <
class InputStorageType,
class OutputStorageType>
338 BIASCDOUT(D_FILTERBASE_CALLSTACK,
"GaussThreshold::Filter7x7 only below threshold\n");
339 SetHalfWinSize(3,
false);
340 if ((_GaussSigma != _LastSigma)||(_GaussRatio != _LastRatio))
341 _CalculateKernels(_GaussSigma, _GaussRatio);
343 const FM_FLOAT h0 = (
const FM_FLOAT)((*_fm.GetSepfh())[3]);
344 const FM_FLOAT h1 = (
const FM_FLOAT)((*_fm.GetSepfh())[2]);
345 const FM_FLOAT h2 = (
const FM_FLOAT)((*_fm.GetSepfh())[1]);
346 const FM_FLOAT h3 = (
const FM_FLOAT)((*_fm.GetSepfh())[0]);
347 const FM_FLOAT v0 = (
const FM_FLOAT)((*_fm.GetSepfv())[3]);
348 const FM_FLOAT v1 = (
const FM_FLOAT)((*_fm.GetSepfv())[2]);
349 const FM_FLOAT v2 = (
const FM_FLOAT)((*_fm.GetSepfv())[1]);
350 const FM_FLOAT v3 = (
const FM_FLOAT)((*_fm.GetSepfv())[0]);
354 BIASERR(
"image with multiple channels. stopping.");
362 if(!_tmpFloat.SamePixelAndChannelCount(src)) {
363 if (!_tmpFloat.IsEmpty()) _tmpFloat.Release();
370 CONV_FLOAT* pD = _tmpFloat.GetImageData();
372 *pD++ = CONV_FLOAT(thresh);
374 *pD++ = CONV_FLOAT(thresh);
376 *pD++ = CONV_FLOAT(thresh);
379 const int width2 = 2*width, width3=3*width;
380 const InputStorageType* pEndH = src.
GetImageData() + width*height-3;
383 register CONV_FLOAT normalization = 0;
384 register CONV_FLOAT accumulator = 0;
387 accumulator += h3*CONV_FLOAT(pS[-3]);
391 accumulator += h2*CONV_FLOAT(pS[-2]);
395 accumulator += h1*CONV_FLOAT(pS[-1]);
399 accumulator += h0*CONV_FLOAT(pS[0]);
403 accumulator += h1*CONV_FLOAT(pS[1]);
408 accumulator += h2*CONV_FLOAT(pS[2]);
412 accumulator += h3*CONV_FLOAT(pS[3]);
416 if (*pS <= OutputStorageType(thresh) && normalization>MIN_NORM)
417 *pD++ = CONV_FLOAT(accumulator / normalization);
419 *pD++ = CONV_FLOAT(*pS);
423 *pD++ = CONV_FLOAT(thresh);pS++;
424 *pD++ = CONV_FLOAT(thresh);pS++;
425 *pD = CONV_FLOAT(thresh);pS++;
427 const CONV_FLOAT cfthresh = CONV_FLOAT(thresh);
430 const CONV_FLOAT* pEndV = _tmpFloat.GetImageData() + width*(height-3);
431 CONV_FLOAT* pI = _tmpFloat.GetImageData();
433 const CONV_FLOAT* pEndFirst3 = _tmpFloat.GetImageData() + 3*width;
434 const CONV_FLOAT* pEndLast3 = _tmpFloat.GetImageData() + width*height;
437 while (pI<pEndFirst3) {
438 *pO++ = OutputStorageType(thresh);
444 register CONV_FLOAT normalization = 0;
445 register CONV_FLOAT accumulator = 0;
447 if (pI[-width3]>cfthresh) {
449 accumulator += v3*CONV_FLOAT(pI[-width3]);
451 if (pI[-width2]>cfthresh) {
453 accumulator += v2*CONV_FLOAT(pI[-width2]);
455 if (pI[-width]>cfthresh) {
457 accumulator += v1*CONV_FLOAT(pI[-width]);
459 if (pI[0]>cfthresh) {
461 accumulator += v0*CONV_FLOAT(pI[0]);
463 if (pI[width]>cfthresh) {
465 accumulator += v1*CONV_FLOAT(pI[width]);
468 if (pI[width2]>cfthresh) {
470 accumulator += v2*CONV_FLOAT(pI[width2]);
472 if (pI[width3]>cfthresh) {
474 accumulator += v3*CONV_FLOAT(pI[width3]);
478 if (*pI <= OutputStorageType(thresh) && normalization > MIN_NORM)
479 *pO++ = OutputStorageType(accumulator / normalization);
481 *pO++ = OutputStorageType(*pI);
485 while (pI < pEndLast3) {
486 *pO++ = OutputStorageType(thresh);
491 unsigned minx, miny, maxx, maxy;
499 if (minx>maxx) minx = maxx = (minx+maxx)/2;
500 if (miny>maxy) miny = maxy = (miny+maxy)/2;
511 #define FILTER_INSTANTIATION_CLASS GaussThreshold
512 #include "Filterinst.hh"
void Release()
reimplemented from ImageBase
generic convolution class.
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
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...
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
bool IsInterleaved() const
double _GaussSigma
the parameter sigma of gaussian kernel
double _GaussRatio
minimum ratio of 1D kernel center and border, ignore smaller entries
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
decides on the image types which FilterFunction should be called
unsigned int GetWidth() const
Gauss< InputStorageType, OutputStorageType > * _GaussIO
ROI * GetROI()
Returns a pointer to the roi object.
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
smoothing with gaussian kernel using a threshold
unsigned int GetHeight() const
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same "size" as Image of other type
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
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
void _CalculateKernels(double Sigma, double Ratio)
calculates the kernel
Gauss< OutputStorageType, OutputStorageType > * _GaussOO
to allow for iterated gauss convolution saving the intermediate image we need a different instance...
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
sets gauss kernel if params changed and calls convolution or fast grey implementation if possible ...
enum EStorageType GetStorageType() const
int Filter7x7GreyOnlyBelowThreshold(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const double thresh)
7x7 gauss filtering, values below threshold are ignored and only pixels below threshold are filed ...
int Filter7x7GreyIgnoreBelowThreshold(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, const double thresh)
7x7 gauss filtering, values below threshold are ignored useful for depth map filtering ...