Visual Servoing Platform  version 3.5.1 under development (2023-09-22)
vpImageFilter.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Various image tools, convolution, ...
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpCannyEdgeDetection.h>
37 #include <visp3/core/vpException.h>
38 #include <visp3/core/vpImageConvert.h>
39 #include <visp3/core/vpImageFilter.h>
40 #include <visp3/core/vpRGBa.h>
41 
45 template<>
46 void vpImageFilter::filter<float>(const vpImage<unsigned char> &I, vpImage<float> &If, const vpArray2D<float> &M, bool convolve);
47 
48 template<>
49 void vpImageFilter::filter<double>(const vpImage<unsigned char> &I, vpImage<double> &If, const vpArray2D<double> &M, bool convolve);
50 
51 template <>
52 void vpImageFilter::filter<float>(const vpImage<float> &I, vpImage<float> &Iu, vpImage<float> &Iv, const vpArray2D<float> &M,
53  bool convolve);
54 
55 template <>
56 void vpImageFilter::filter<double>(const vpImage<double> &I, vpImage<double> &Iu, vpImage<double> &Iv, const vpArray2D<double> &M,
57  bool convolve);
114  const vpColVector &kernelV)
115 {
116  unsigned int size = kernelH.size();
117  unsigned int half_size = size / 2;
118 
119  If.resize(I.getHeight(), I.getWidth(), 0.0);
120  vpImage<double> I_filter(I.getHeight(), I.getWidth(), 0.0);
121 
122  for (unsigned int i = 0; i < I.getHeight(); i++) {
123  for (unsigned int j = half_size; j < I.getWidth() - half_size; j++) {
124  double conv = 0.0;
125  for (unsigned int a = 0; a < kernelH.size(); a++) {
126  conv += kernelH[a] * I[i][j + half_size - a];
127  }
128 
129  I_filter[i][j] = conv;
130  }
131  }
132 
133  for (unsigned int i = half_size; i < I.getHeight() - half_size; i++) {
134  for (unsigned int j = 0; j < I.getWidth(); j++) {
135  double conv = 0.0;
136  for (unsigned int a = 0; a < kernelV.size(); a++) {
137  conv += kernelV[a] * I_filter[i + half_size - a][j];
138  }
139 
140  If[i][j] = conv;
141  }
142  }
143 }
144 
145 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
151 float vpImageFilter::median(const cv::Mat &channel)
152 {
153  float m = (channel.rows * channel.cols) / 2.f;
154  int bin = 0;
155  float med = -1.0f;
156 
157  int histSize = 256;
158  float range[] = { 0, 256 };
159  const float *histRange = { range };
160  bool uniform = true;
161  bool accumulate = false;
162  cv::Mat hist;
163  cv::calcHist(&channel, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
164 
165  for (int i = 0; i < histSize && med < 0.0; ++i) {
166  bin += cvRound(hist.at<float>(i));
167  if (bin > m && med < 0.0)
168  med = static_cast<float>(i);
169  }
170 
171  return med;
172 }
173 
182 {
183  cv::Mat cv_I;
184  vpImageConvert::convert(Isrc, cv_I);
185  return median(cv_I);
186 }
187 
196 std::vector<float> vpImageFilter::median(const vpImage<vpRGBa> &Isrc)
197 {
198  cv::Mat cv_I_bgr;
199  vpImageConvert::convert(Isrc, cv_I_bgr);
200  std::vector<cv::Mat> channels;
201  cv::split(cv_I_bgr, channels);
202  std::vector<float> meds(3);
203  const int orderMeds[] = { 2, 1, 0 }; // To keep the order R, G, B
204  const int orderCvChannels[] = { 0, 1, 2 }; // Because the order of the cv::Mat is B, G, R
205  for (unsigned int i = 0; i < 3; i++) {
206  meds[orderMeds[i]] = median(channels[orderCvChannels[i]]);
207  }
208  return meds;
209 }
210 
219 float vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh)
220 {
221  cv::Mat cv_I_blur;
222  if (p_cv_blur != nullptr) {
223  cv_I_blur = *p_cv_blur;
224  }
225  else {
226  cv::GaussianBlur(cv_I, cv_I_blur, cv::Size(9, 9), 2, 2);
227  }
228 
229  // Subsample image to reach a 256 x 256 size
230  int req_size = 256;
231  int orig_size = std::min(static_cast<int>(cv_I.rows), static_cast<int>(cv_I.cols));
232  int scale_down = std::max(1, static_cast<int>(orig_size / req_size));
233  cv::Mat cv_I_scaled_down;
234  resize(cv_I_blur, cv_I_scaled_down, cv::Size(), scale_down, scale_down, cv::INTER_NEAREST);
235 
236  float median_pix = vpImageFilter::median(cv_I_scaled_down);
237  float lower = std::max(0.f, 0.7f * median_pix);
238  float upper = std::min(255.f, 1.3f * median_pix);
239  upper = std::max(1.f, upper);
240  lowerThresh = lower;
241  return upper;
242 }
243 
252 {
253  cv::Mat cv_I;
254  vpImageConvert::convert(I, cv_I);
255  return computeCannyThreshold(cv_I, nullptr, lowerThresh);
256 }
257 #endif
258 
299  unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
300 {
301  vpImageFilter::canny(Isrc, Ires, gaussianFilterSize, thresholdCanny / 3.f, thresholdCanny, apertureSobel);
302 }
303 
348  unsigned int gaussianFilterSize, float lowerThreshold, float upperThreshold, unsigned int apertureSobel)
349 {
350 #if defined(HAVE_OPENCV_IMGPROC)
351  cv::Mat img_cvmat, cv_I_blur, cv_dx, cv_dy, edges_cvmat;
352  vpImageConvert::convert(Isrc, img_cvmat);
353  cv::GaussianBlur(img_cvmat, cv_I_blur, cv::Size((int)gaussianFilterSize, (int)gaussianFilterSize), 0, 0);
354  cv::Sobel(cv_I_blur, cv_dx, CV_16S, 1, 0, apertureSobel);
355  cv::Sobel(cv_I_blur, cv_dy, CV_16S, 0, 1, apertureSobel);
356  float upperCannyThresh = upperThreshold;
357  float lowerCannyThresh = lowerThreshold;
358  if (upperCannyThresh < 0) {
359  upperCannyThresh = computeCannyThreshold(img_cvmat, &cv_I_blur, lowerCannyThresh);
360  }
361  else if (lowerCannyThresh < 0) {
362  lowerCannyThresh = upperCannyThresh / 3.f;
363  }
364  cv::Canny(cv_dx, cv_dy, edges_cvmat, lowerCannyThresh, upperCannyThresh, false);
365  vpImageConvert::convert(edges_cvmat, Ires);
366 #else
367  (void)apertureSobel;
368  float upperCannyThresh = upperThreshold;
369  float lowerCannyThresh = lowerThreshold;
370  if (upperCannyThresh < 0) {
371  throw(vpException(vpException::badValue, "OpenCV imgproc module missing to be able to compute automatically the Canny thresholds"));
372  }
373  else if (lowerCannyThresh < 0) {
374  lowerCannyThresh = upperCannyThresh / 3.;
375  }
376  vpCannyEdgeDetection edgeDetector(gaussianFilterSize, 0.1, lowerCannyThresh, upperCannyThresh);
377  Ires = edgeDetector.detect(Isrc);
378 #endif
379 }
380 
384 template<>
385 void vpImageFilter::filter<float>(const vpImage<unsigned char> &I, vpImage<float> &GI, const float *filter,
386  unsigned int size);
387 
388 template<>
389 void vpImageFilter::filter<double>(const vpImage<unsigned char> &I, vpImage<double> &GI, const double *filter,
390  unsigned int size);
391 
392 template<>
393 void vpImageFilter::filter<float>(const vpImage<float> &I, vpImage<float> &GI, const float *filter, unsigned int size);
394 
395 template<>
396 void vpImageFilter::filter<double>(const vpImage<double> &I, vpImage<double> &GI, const double *filter, unsigned int size);
397 
398 template<>
399 void vpImageFilter::filterX<float>(const vpImage<unsigned char> &I, vpImage<float> &dIx, const float *filter,
400  unsigned int size);
401 
402 template<>
403 void vpImageFilter::filterX<double>(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter,
404  unsigned int size);
409 void vpImageFilter::filterX(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size)
410 {
411  dIx.resize(I.getHeight(), I.getWidth());
412  for (unsigned int i = 0; i < I.getHeight(); i++) {
413  for (unsigned int j = 0; j < (size - 1) / 2; j++) {
414  dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderR(I, i, j, filter, size));
415  dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderG(I, i, j, filter, size));
416  dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderB(I, i, j, filter, size));
417  }
418  for (unsigned int j = (size - 1) / 2; j < I.getWidth() - (size - 1) / 2; j++) {
419  dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXR(I, i, j, filter, size));
420  dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXG(I, i, j, filter, size));
421  dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXB(I, i, j, filter, size));
422  }
423  for (unsigned int j = I.getWidth() - (size - 1) / 2; j < I.getWidth(); j++) {
424  dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXRightBorderR(I, i, j, filter, size));
425  dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXRightBorderG(I, i, j, filter, size));
426  dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXRightBorderB(I, i, j, filter, size));
427  }
428  }
429 }
430 
434 template<>
435 void vpImageFilter::filterX<float>(const vpImage<float> &I, vpImage<float> &dIx, const float *filter, unsigned int size);
436 
437 template<>
438 void vpImageFilter::filterX<double>(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
439 
440 template<>
441 void vpImageFilter::filterY<float>(const vpImage<unsigned char> &I, vpImage<float> &dIy, const float *filter,
442  unsigned int size);
443 
444 template<>
445 void vpImageFilter::filterY<double>(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *filter,
446  unsigned int size);
451 void vpImageFilter::filterY(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIy, const double *filter, unsigned int size)
452 {
453  dIy.resize(I.getHeight(), I.getWidth());
454  for (unsigned int i = 0; i < (size - 1) / 2; i++) {
455  for (unsigned int j = 0; j < I.getWidth(); j++) {
456  dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYTopBorderR(I, i, j, filter, size));
457  dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYTopBorderG(I, i, j, filter, size));
458  dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYTopBorderB(I, i, j, filter, size));
459  }
460  }
461  for (unsigned int i = (size - 1) / 2; i < I.getHeight() - (size - 1) / 2; i++) {
462  for (unsigned int j = 0; j < I.getWidth(); j++) {
463  dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYR(I, i, j, filter, size));
464  dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYG(I, i, j, filter, size));
465  dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYB(I, i, j, filter, size));
466  }
467  }
468  for (unsigned int i = I.getHeight() - (size - 1) / 2; i < I.getHeight(); i++) {
469  for (unsigned int j = 0; j < I.getWidth(); j++) {
470  dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderR(I, i, j, filter, size));
471  dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderG(I, i, j, filter, size));
472  dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderB(I, i, j, filter, size));
473  }
474  }
475 }
476 
480 template<>
481 void vpImageFilter::filterY<float>(const vpImage<float> &I, vpImage<float> &dIy, const float *filter, unsigned int size);
482 
483 template<>
484 void vpImageFilter::filterY<double>(const vpImage<double> &I, vpImage<double> &dIy, const double *filter, unsigned int size)
485 {
486  dIy.resize(I.getHeight(), I.getWidth());
487  for (unsigned int i = 0; i < (size - 1) / 2; i++) {
488  for (unsigned int j = 0; j < I.getWidth(); j++) {
489  dIy[i][j] = vpImageFilter::filterYTopBorder(I, i, j, filter, size);
490  }
491  }
492  for (unsigned int i = (size - 1) / 2; i < I.getHeight() - (size - 1) / 2; i++) {
493  for (unsigned int j = 0; j < I.getWidth(); j++) {
494  dIy[i][j] = vpImageFilter::filterY(I, i, j, filter, size);
495  }
496  }
497  for (unsigned int i = I.getHeight() - (size - 1) / 2; i < I.getHeight(); i++) {
498  for (unsigned int j = 0; j < I.getWidth(); j++) {
499  dIy[i][j] = vpImageFilter::filterYBottomBorder(I, i, j, filter, size);
500  }
501  }
502 }
503 
504 template<>
505 void vpImageFilter::gaussianBlur<float>(const vpImage<unsigned char> &I, vpImage<float> &GI, unsigned int size, float sigma, bool normalize);
506 
507 template<>
508 void vpImageFilter::gaussianBlur<double>(const vpImage<unsigned char> &I, vpImage<double> &GI, unsigned int size, double sigma, bool normalize);
524 void vpImageFilter::gaussianBlur(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &GI, unsigned int size, double sigma, bool normalize)
525 {
526  double *fg = new double[(size + 1) / 2];
527  vpImageFilter::getGaussianKernel(fg, size, sigma, normalize);
528  vpImage<vpRGBa> GIx;
529  vpImageFilter::filterX(I, GIx, fg, size);
530  vpImageFilter::filterY(GIx, GI, fg, size);
531  GIx.destroy();
532  delete[] fg;
533 }
534 
538 template<>
539 void vpImageFilter::gaussianBlur<float>(const vpImage<float> &I, vpImage<float> &GI, unsigned int size, float sigma, bool normalize);
540 
541 template<>
542 void vpImageFilter::gaussianBlur<double>(const vpImage<double> &I, vpImage<double> &GI, unsigned int size, double sigma, bool normalize);
543 
544 template<>
545 void vpImageFilter::getGaussianKernel<float>(float *filter, unsigned int size, float sigma, bool normalize);
546 
547 template <>
548 void vpImageFilter::getGaussianDerivativeKernel<float>(float *filter, unsigned int size, float sigma, bool normalize);
549 
550 template <>
551 void vpImageFilter::getGaussianDerivativeKernel<double>(double *filter, unsigned int size, double sigma, bool normalize);
552 
553 template<>
554 void vpImageFilter::getGradX<float>(const vpImage<unsigned char> &I, vpImage<float> &dIx);
555 
556 template<>
557 void vpImageFilter::getGradX<double>(const vpImage<unsigned char> &I, vpImage<double> &dIx);
558 
559 template<>
560 void vpImageFilter::getGradY<float>(const vpImage<unsigned char> &I, vpImage<float> &dIy);
561 
562 template<>
563 void vpImageFilter::getGradY<double>(const vpImage<unsigned char> &I, vpImage<double> &dIy);
564 
565 template<>
566 void vpImageFilter::getGradX<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIx, const float *filter, unsigned int size);
567 
568 template<>
569 void vpImageFilter::getGradX<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
570 
571 template<>
572 void vpImageFilter::getGradX<float, float>(const vpImage<float> &I, vpImage<float> &dIx, const float *filter, unsigned int size);
573 
574 template<>
575 void vpImageFilter::getGradX<double, double>(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
576 
577 template<>
578 void vpImageFilter::getGradY<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIy, const float *filter, unsigned int size);
579 
580 template<>
581 void vpImageFilter::getGradY<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *filter, unsigned int size);
582 
583 template<>
584 void vpImageFilter::getGradY<float, float>(const vpImage<float> &I, vpImage<float> &dIy, const float *filter, unsigned int size);
585 
586 template<>
587 void vpImageFilter::getGradY<double, double>(const vpImage<double> &I, vpImage<double> &dIy, const double *filter, unsigned int size);
588 
589 template<>
590 void vpImageFilter::getGradXGauss2D<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIx, const float *gaussianKernel,
591  const float *gaussianDerivativeKernel, unsigned int size);
592 
593 template<>
594 void vpImageFilter::getGradXGauss2D<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *gaussianKernel,
595  const double *gaussianDerivativeKernel, unsigned int size);
596 
597 template<>
598 void vpImageFilter::getGradXGauss2D<float, float>(const vpImage<float> &I, vpImage<float> &dIx, const float *gaussianKernel,
599  const float *gaussianDerivativeKernel, unsigned int size);
600 
601 template<>
602 void vpImageFilter::getGradXGauss2D<double, double>(const vpImage<double> &I, vpImage<double> &dIx, const double *gaussianKernel,
603  const double *gaussianDerivativeKernel, unsigned int size);
604 
605 template<>
606 void vpImageFilter::getGradYGauss2D<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIy, const float *gaussianKernel,
607  const float *gaussianDerivativeKernel, unsigned int size);
608 
609 template<>
610 void vpImageFilter::getGradYGauss2D<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *gaussianKernel,
611  const double *gaussianDerivativeKernel, unsigned int size);
612 
613 template<>
614 void vpImageFilter::getGradYGauss2D<float, float>(const vpImage<float> &I, vpImage<float> &dIy, const float *gaussianKernel,
615  const float *gaussianDerivativeKernel, unsigned int size);
616 
617 template<>
618 void vpImageFilter::getGradYGauss2D<double, double>(const vpImage<double> &I, vpImage<double> &dIy, const double *gaussianKernel,
619  const double *gaussianDerivativeKernel, unsigned int size);
624 // Operation for Gaussian pyramid
626 {
628 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
629 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
630  cv::Mat imgsrc, imgdest;
631  vpImageConvert::convert(I, imgsrc);
632  cv::pyrDown(imgsrc, imgdest, cv::Size((int)I.getWidth() / 2, (int)I.getHeight() / 2));
633  vpImageConvert::convert(imgdest, GI);
634 #else
635  cv::Mat imgsrc, imgdest;
636  vpImageConvert::convert(I, imgsrc);
637  cv::pyrDown(imgsrc, imgdest, cvSize((int)I.getWidth() / 2, (int)I.getHeight() / 2));
638  vpImageConvert::convert(imgdest, GI);
639 #endif
640 #else
643 #endif
644 }
645 
647 {
648  unsigned int w = I.getWidth() / 2;
649 
650  GI.resize(I.getHeight(), w);
651  for (unsigned int i = 0; i < I.getHeight(); i++) {
652  GI[i][0] = I[i][0];
653  for (unsigned int j = 1; j < w - 1; j++) {
654  GI[i][j] = vpImageFilter::filterGaussXPyramidal(I, i, 2 * j);
655  }
656  GI[i][w - 1] = I[i][2 * w - 1];
657  }
658 }
659 
661 {
662  unsigned int h = I.getHeight() / 2;
663 
664  GI.resize(h, I.getWidth());
665  for (unsigned int j = 0; j < I.getWidth(); j++) {
666  GI[0][j] = I[0][j];
667  for (unsigned int i = 1; i < h - 1; i++) {
668  GI[i][j] = vpImageFilter::filterGaussYPyramidal(I, 2 * i, j);
669  }
670  GI[h - 1][j] = I[2 * h - 1][j];
671  }
672 }
673 
677 template<>
678 double vpImageFilter::getSobelKernelX<double>(double *filter, unsigned int size);
679 
680 template<>
681 float vpImageFilter::getSobelKernelX<float>(float *filter, unsigned int size);
682 
683 template<>
684 double vpImageFilter::getSobelKernelY<double>(double *filter, unsigned int size);
685 
686 template<>
687 float vpImageFilter::getSobelKernelY<float>(float *filter, unsigned int size);
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:292
json namespace shortcut
vpImage< unsigned char > detect(const vpImage< vpRGBa > &I_color)
Detect the edges in an image. Convert the color image into a gray-scale image.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:167
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static double filterYTopBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYB(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static double filterYBottomBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh)
Compute the upper Canny edge filter threshold.
static void filterX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size)
static double filterXRightBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYBottomBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYTopBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterXB(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static double filterXLeftBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYR(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void sepFilter(const vpImage< unsigned char > &I, vpImage< double > &If, const vpColVector &kernelH, const vpColVector &kernelV)
static void gaussianBlur(const vpImage< unsigned char > &I, vpImage< FilterType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true)
static double filterXLeftBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static FilterType filterYBottomBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterXLeftBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterXRightBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterXR(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void getGaussXPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static void getGaussianKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static double filterYTopBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void getGaussYPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static float median(const cv::Mat &cv_I)
Calculates the median value of a single channel. The algorithm is based on based on https://github....
static double filterXRightBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterY(const vpImage< unsigned char > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size)
static void filter(const vpImage< unsigned char > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false)
static void filterXG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
static FilterType filterYTopBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterYBottomBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static unsigned char filterGaussYPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void getGaussPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
void destroy()
Destructor : Memory de-allocation.
Definition: vpImage.h:824
unsigned int getWidth() const
Definition: vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:795
unsigned int getHeight() const
Definition: vpImage.h:184