34 #ifndef _vpImageFilter_h_
35 #define _vpImageFilter_h_
47 #include <visp3/core/vpConfig.h>
48 #include <visp3/core/vpException.h>
49 #include <visp3/core/vpHistogram.h>
50 #include <visp3/core/vpImage.h>
51 #include <visp3/core/vpImageConvert.h>
52 #include <visp3/core/vpImageException.h>
53 #include <visp3/core/vpMath.h>
54 #include <visp3/core/vpMatrix.h>
55 #include <visp3/core/vpRGBa.h>
57 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
58 #include <opencv2/imgproc/imgproc.hpp>
59 #include <opencv2/imgproc/imgproc_c.h>
82 template<
typename ImageType>
85 if (p_mask ==
nullptr) {
91 I.
resize(height, width,
static_cast<ImageType
>(0));
104 static bool checkBooleanMask(
const vpImage<bool> *p_mask,
const unsigned int &r,
const unsigned int &c)
106 bool computeVal =
true;
107 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
108 if (p_mask !=
nullptr)
113 computeVal = (*p_mask)[r][c];
120 #if ((__cplusplus <= 199711L) || (defined(_MSVC_LANG) && (_MSVC_LANG == 199711L)))
122 template <
typename FilterType>
125 const unsigned int nbRows = filter.
getRows();
126 const unsigned int nbCols = filter.
getCols();
127 for (
unsigned int r = 0; r < nbRows; ++r) {
128 for (
unsigned int c = 0; c < nbCols; ++c) {
129 filter[r][c] = filter[r][c] * scale;
139 CANNY_OPENCV_BACKEND = 0,
140 CANNY_VISP_BACKEND = 1,
141 CANNY_COUNT_BACKEND = 2
142 } vpCannyBackendType;
144 static std::string vpCannyBackendTypeList(
const std::string &pref =
"<",
const std::string &sep =
" , ",
145 const std::string &suf =
">");
147 static std::string vpCannyBackendTypeToString(
const vpCannyBackendType &type);
149 static vpCannyBackendType vpCannyBackendTypeFromString(
const std::string &name);
154 CANNY_GBLUR_SOBEL_FILTERING = 0,
155 CANNY_GBLUR_SCHARR_FILTERING = 1,
156 CANNY_COUNT_FILTERING = 2
157 } vpCannyFilteringAndGradientType;
159 static std::string vpCannyFilteringAndGradientTypeList(
const std::string &pref =
"<",
const std::string &sep =
" , ",
160 const std::string &suf =
">");
162 static std::string vpCannyFilteringAndGradientTypeToString(
const vpCannyFilteringAndGradientType &type);
164 static vpCannyFilteringAndGradientType vpCannyFilteringAndGradientTypeFromString(
const std::string &name);
167 const float &thresholdCanny,
const unsigned int &apertureSobel);
170 const float &lowerThresholdCanny,
const float &higherThresholdCanny,
171 const unsigned int &apertureSobel);
174 const float &lowerThresholdCanny,
const float &higherThresholdCanny,
175 const unsigned int &apertureSobel,
const float &gaussianStdev,
const float &lowerThresholdRatio,
176 const float &upperThresholdRatio,
const bool &normalizeGradients,
177 const vpCannyBackendType &cannyBackend,
const vpCannyFilteringAndGradientType &cannyFilteringSteps,
180 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
181 static float computeCannyThreshold(
const cv::Mat &cv_I,
const cv::Mat *p_cv_dIx,
const cv::Mat *p_cv_dIy,
182 float &lowerThresh,
const unsigned int &gaussianKernelSize = 5,
183 const float &gaussianStdev = 2.f,
const unsigned int &apertureGradient = 3,
184 const float &lowerThresholdRatio = 0.6,
const float &upperThresholdRatio = 0.8,
185 const vpCannyFilteringAndGradientType &filteringType = CANNY_GBLUR_SOBEL_FILTERING);
187 static void computePartialDerivatives(
const cv::Mat &cv_I,
188 cv::Mat &cv_dIx, cv::Mat &cv_dIy,
189 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
190 const unsigned int &gaussianKernelSize = 5,
const float &gaussianStdev = 2.f,
191 const unsigned int &apertureGradient = 3,
192 const vpCannyFilteringAndGradientType &filteringType = CANNY_GBLUR_SOBEL_FILTERING);
215 template <
typename ImageType,
typename FilterType>
218 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
219 const unsigned int &gaussianKernelSize = 5,
const FilterType &gaussianStdev = 2.f,
220 const unsigned int &apertureGradient = 3,
225 if (backend == CANNY_OPENCV_BACKEND) {
226 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
227 cv::Mat cv_I, cv_dIx, cv_dIy;
229 computePartialDerivatives(cv_I, cv_dIx, cv_dIy, computeDx, computeDy, normalize, gaussianKernelSize,
230 static_cast<float>(gaussianStdev), apertureGradient, filteringType);
242 if ((filteringType == CANNY_GBLUR_SCHARR_FILTERING) || (filteringType == CANNY_GBLUR_SOBEL_FILTERING)) {
253 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
256 const unsigned int nbRows = filter.
getRows();
257 const unsigned int nbCols = filter.
getCols();
258 for (
unsigned int r = 0; r < nbRows; ++r) {
259 for (
unsigned int c = 0; c < nbCols; ++c) {
260 filter[r][c] = filter[r][c] * scale;
270 if (filteringType == CANNY_GBLUR_SOBEL_FILTERING) {
278 else if (filteringType == CANNY_GBLUR_SCHARR_FILTERING) {
290 scaleFilter(gradientFilterX, scaleX);
293 scaleFilter(gradientFilterY, scaleY);
307 std::string errMsg =
"[vpImageFilter::computePartialDerivatives] Filtering + gradient method \"";
308 errMsg += vpCannyFilteringAndGradientTypeToString(filteringType);
309 errMsg +=
"\" is not implemented yet\n";
315 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
316 template <
typename FilterType>
319 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
320 const unsigned int &gaussianKernelSize = 5,
const FilterType &gaussianStdev = 2.f,
321 const unsigned int &apertureGradient = 3,
322 const vpCannyFilteringAndGradientType &filteringType = CANNY_GBLUR_SOBEL_FILTERING,
323 const vpCannyBackendType &backend = CANNY_VISP_BACKEND,
const vpImage<bool> *p_mask =
nullptr) =
delete;
325 template <
typename ImageType>
328 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
329 const unsigned int &gaussianKernelSize = 5,
const unsigned char &gaussianStdev = 2.f,
330 const unsigned int &apertureGradient = 3,
331 const vpCannyFilteringAndGradientType &filteringType = CANNY_GBLUR_SOBEL_FILTERING,
332 const vpCannyBackendType &backend = CANNY_VISP_BACKEND,
const vpImage<bool> *p_mask =
nullptr) =
delete;
334 template <
typename ImageType>
337 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
338 const unsigned int gaussianKernelSize = 5,
const vpRGBa gaussianStdev =
vpRGBa(),
339 const unsigned int apertureGradient = 3,
340 const vpCannyFilteringAndGradientType &filteringType = CANNY_GBLUR_SOBEL_FILTERING,
341 const vpCannyBackendType &backend = CANNY_VISP_BACKEND,
const vpImage<bool> *p_mask =
nullptr) =
delete;
343 template <
typename FilterType>
346 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
347 const unsigned int &gaussianKernelSize = 5,
const FilterType &gaussianStdev = 2.f,
348 const unsigned int &apertureGradient = 3,
352 template <
typename ImageType>
355 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
356 const unsigned int &gaussianKernelSize = 5,
const unsigned char &gaussianStdev = 2.f,
357 const unsigned int &apertureGradient = 3,
361 template <
typename ImageType>
364 const bool &computeDx =
true,
const bool &computeDy =
true,
const bool &normalize =
true,
365 const unsigned int gaussianKernelSize = 5,
const vpRGBa gaussianStdev =
vpRGBa(),
366 const unsigned int apertureGradient = 3,
391 template<
typename OutType>
394 const unsigned int &gaussianKernelSize = 5,
395 const OutType &gaussianStdev = 2.f,
const unsigned int &apertureGradient = 3,
396 const float &lowerThresholdRatio = 0.6,
const float &upperThresholdRatio = 0.8,
400 const unsigned int w = I.
getWidth();
405 if ((p_dIx !=
nullptr) && (p_dIy !=
nullptr)) {
410 computePartialDerivatives(I, dIx, dIy,
true,
true,
true, gaussianKernelSize, gaussianStdev,
415 for (
unsigned int r = 0; r < h; ++r) {
416 for (
unsigned int c = 0; c < w; ++c) {
419 bool computeVal = checkBooleanMask(p_mask, r, c);
422 float dx =
static_cast<float>(dIx[r][c]);
423 float dy =
static_cast<float>(dIy[r][c]);
424 float gradient = std::abs(dx) + std::abs(dy);
425 float gradientClamped = std::min<float>(gradient,
static_cast<float>(std::numeric_limits<unsigned char>::max()));
426 dI[r][c] =
static_cast<unsigned char>(gradientClamped);
434 const unsigned int nbBins = 256;
436 float totalNbPixels =
static_cast<float>(hist.
getTotal());
438 float t = upperThresholdRatio * totalNbPixels;
440 for (
unsigned int i = 0; i < nbBins; ++i) {
441 float tf =
static_cast<float>(hist[i]);
448 float upperThresh = std::max<float>(bon, 1.f);
449 lowerThresh = lowerThresholdRatio * bon;
462 return (2047.0 *
static_cast<double>(I[r][c + 1] - I[r][c - 1]) + 913.0 *
static_cast<double>(I[r][c + 2] - I[r][c - 2]) +
463 112.0 *
static_cast<double>(I[r][c + 3] - I[r][c - 3])) / 8418.0;
475 return (2047.0 *
static_cast<double>(I[r + 1][c] - I[r - 1][c]) + 913.0 *
static_cast<double>(I[r + 2][c] - I[r - 2][c]) +
476 112.0 *
static_cast<double>(I[r + 3][c] - I[r - 3][c])) / 8418.0;
492 template <
class ImageType,
typename FilterType>
495 const unsigned int stop = (size - 1) / 2;
501 for (i = 1; i <= stop; ++i) {
502 result += filter[i] *
static_cast<FilterType
>(I[r][c + i] - I[r][c - i]);
520 template <
class ImageType,
typename FilterType>
523 const unsigned int stop = (size - 1) / 2;
529 for (i = 1; i <= stop; ++i) {
530 result += filter[i] *
static_cast<FilterType
>(I[r + i][c] - I[r - i][c]);
564 template <
typename ImageType,
typename FilterType>
569 const unsigned int half_size_y = size_y / 2, half_size_x = size_x / 2;
572 If.
resize(inputHeight, inputWidth, 0.0);
575 const unsigned int stopHeight = inputHeight - half_size_y;
576 const unsigned int stopWidth = inputWidth - half_size_x;
577 for (
unsigned int i = half_size_y; i < stopHeight; ++i) {
578 for (
unsigned int j = half_size_x; j < stopWidth; ++j) {
581 bool computeVal = checkBooleanMask(p_mask, i, j);
585 for (
unsigned int a = 0; a < size_y; ++a) {
586 for (
unsigned int b = 0; b < size_x; ++b) {
587 FilterType val =
static_cast<FilterType
>(I[i + half_size_y - a][j + half_size_x - b]);
588 conv += M[a][b] * val;
597 const unsigned int stopHeight = inputHeight - half_size_y;
598 const unsigned int stopWidth = inputWidth - half_size_x;
599 for (
unsigned int i = half_size_y; i < stopHeight; ++i) {
600 for (
unsigned int j = half_size_x; j < stopWidth; ++j) {
603 bool computeVal = checkBooleanMask(p_mask, i, j);
607 for (
unsigned int a = 0; a < size_y; ++a) {
608 for (
unsigned int b = 0; b < size_x; ++b) {
609 FilterType val =
static_cast<FilterType
>(I[i - half_size_y + a][j - half_size_x + b]);
610 corr += M[a][b] * val;
620 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
621 template <
typename FilterType>
624 template <
typename FilterType>
641 template <
typename ImageType,
typename FilterType>
643 bool convolve =
false,
const vpImage<bool> *p_mask =
nullptr)
645 const unsigned int size = M.
getRows();
646 const unsigned int half_size = size / 2;
648 const unsigned int stopV = height - half_size;
649 const unsigned int stopU = width - half_size;
651 Iu.
resize(height, width, 0.0);
652 Iv.
resize(height, width, 0.0);
655 for (
unsigned int v = half_size; v < stopV; ++v) {
656 for (
unsigned int u = half_size; u < stopU; ++u) {
659 bool computeVal = checkBooleanMask(p_mask, v, u);
661 FilterType conv_u = 0;
662 FilterType conv_v = 0;
664 for (
unsigned int a = 0; a < size; ++a) {
665 for (
unsigned int b = 0; b < size; ++b) {
666 FilterType val =
static_cast<FilterType
>(I[v + half_size - a][u + half_size - b]);
667 conv_u += M[a][b] * val;
668 conv_v += M[b][a] * val;
678 for (
unsigned int v = half_size; v < stopV; ++v) {
679 for (
unsigned int u = half_size; u < stopU; ++u) {
682 bool computeVal = checkBooleanMask(p_mask, v, u);
685 FilterType conv_u = 0;
686 FilterType conv_v = 0;
688 for (
unsigned int a = 0; a < size; ++a) {
689 for (
unsigned int b = 0; b < size; ++b) {
690 FilterType val =
static_cast<FilterType
>(I[v - half_size + a][u - half_size + b]);
691 conv_u += M[a][b] * val;
692 conv_v += M[b][a] * val;
703 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
704 template<
typename FilterType>
707 template<
typename ImageType>
710 template<
typename FilterType>
713 template<
typename ImageType>
728 template <
typename ImageType,
typename FilterType>
732 filterX<ImageType, FilterType>(I, GIx, filter, size, p_mask);
733 filterY<FilterType, FilterType>(GIx, GI, filter, size, p_mask);
739 return static_cast<unsigned char>((1. * I[i][j - 2] + 4. * I[i][j - 1] + 6. * I[i][j] + 4. * I[i][j + 1] + 1. * I[i][j + 2]) / 16.);
743 return static_cast<unsigned char>((1. * I[i - 2][j] + 4. * I[i - 1][j] + 6. * I[i][j] + 4. * I[i + 1][j] + 1. * I[i + 2][j]) / 16.);
746 template <
typename ImageType,
typename FilterType>
750 const unsigned int height = I.
getHeight();
751 const unsigned int width = I.
getWidth();
752 const unsigned int stop1J = (size - 1) / 2;
753 const unsigned int stop2J = width - (size - 1) / 2;
754 resizeAndInitializeIfNeeded(p_mask, height, width, dIx);
756 for (
unsigned int i = 0; i < height; ++i) {
757 for (
unsigned int j = 0; j < stop1J; ++j) {
760 bool computeVal = checkBooleanMask(p_mask, i, j);
762 dIx[i][j] = vpImageFilter::filterXLeftBorder<ImageType, FilterType>(I, i, j, filter, size);
765 for (
unsigned int j = stop1J; j < stop2J; ++j) {
768 bool computeVal = checkBooleanMask(p_mask, i, j);
770 dIx[i][j] = vpImageFilter::filterX<ImageType, FilterType>(I, i, j, filter, size);
773 for (
unsigned int j = stop2J; j < width; ++j) {
776 bool computeVal = checkBooleanMask(p_mask, i, j);
778 dIx[i][j] = vpImageFilter::filterXRightBorder<ImageType, FilterType>(I, i, j, filter, size);
786 #ifdef DOXYGEN_SHOULD_SKIP_THIS
792 template<
typename ImageType,
typename FilterType>
793 static inline FilterType
filterX(
const vpImage<ImageType> &I,
unsigned int r,
unsigned int c,
const FilterType *filter,
unsigned int size)
795 const unsigned int stop = (size - 1) / 2;
796 FilterType result =
static_cast<FilterType
>(0.);
798 for (
unsigned int i = 1; i <= stop; ++i) {
799 result += filter[i] *
static_cast<FilterType
>(I[r][c + i] + I[r][c - i]);
801 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
804 #ifndef DOXYGEN_SHOULD_SKIP_THIS
805 static inline double filterXR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
807 const unsigned int stop = (size - 1) / 2;
809 for (
unsigned int i = 1; i <= stop; ++i) {
810 result += filter[i] *
static_cast<double>(I[r][c + i].R + I[r][c - i].R);
812 return result + filter[0] *
static_cast<double>(I[r][c].R);
815 static inline double filterXG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
817 const unsigned int stop = (size - 1) / 2;
820 for (
unsigned int i = 1; i <= stop; ++i) {
821 result += filter[i] *
static_cast<double>(I[r][c + i].G + I[r][c - i].G);
823 return result + filter[0] *
static_cast<double>(I[r][c].G);
826 static inline double filterXB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
828 const unsigned int stop = (size - 1) / 2;
831 for (
unsigned int i = 1; i <= stop; ++i) {
832 result += filter[i] *
static_cast<double>(I[r][c + i].B + I[r][c - i].B);
834 return result + filter[0] *
static_cast<double>(I[r][c].B);
837 template <
typename ImageType,
typename FilterType>
838 static inline FilterType filterXLeftBorder(
const vpImage<ImageType> &I,
unsigned int r,
unsigned int c,
839 const FilterType *filter,
unsigned int size)
841 const unsigned int stop = (size - 1) / 2;
842 FilterType result =
static_cast<FilterType
>(0.);
844 for (
unsigned int i = 1; i <= stop; ++i) {
846 result += filter[i] *
static_cast<FilterType
>(I[r][c + i] + I[r][c - i]);
849 result += filter[i] *
static_cast<FilterType
>(I[r][c + i] + I[r][i - c]);
852 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
855 static inline double filterXLeftBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
856 const double *filter,
unsigned int size)
858 const unsigned int stop = (size - 1) / 2;
861 for (
unsigned int i = 1; i <= stop; ++i) {
863 result += filter[i] *
static_cast<double>(I[r][c + i].R + I[r][c - i].R);
866 result += filter[i] *
static_cast<double>(I[r][c + i].R + I[r][i - c].R);
869 return result + filter[0] *
static_cast<double>(I[r][c].R);
872 static inline double filterXLeftBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
873 const double *filter,
unsigned int size)
875 const unsigned int stop = (size - 1) / 2;
878 for (
unsigned int i = 1; i <= stop; ++i) {
880 result += filter[i] *
static_cast<double>(I[r][c + i].G + I[r][c - i].G);
883 result += filter[i] *
static_cast<double>(I[r][c + i].G + I[r][i - c].G);
886 return result + filter[0] *
static_cast<double>(I[r][c].G);
889 static inline double filterXLeftBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
890 const double *filter,
unsigned int size)
892 const unsigned int stop = (size - 1) / 2;
895 for (
unsigned int i = 1; i <= stop; ++i) {
897 result += filter[i] *
static_cast<double>(I[r][c + i].B + I[r][c - i].B);
900 result += filter[i] *
static_cast<double>(I[r][c + i].B + I[r][i - c].B);
903 return result + filter[0] *
static_cast<double>(I[r][c].B);
906 template <
typename ImageType,
typename FilterType>
907 static inline FilterType filterXRightBorder(
const vpImage<ImageType> &I,
unsigned int r,
unsigned int c,
908 const FilterType *filter,
unsigned int size)
910 const unsigned int stop = (size - 1) / 2;
911 const unsigned int width = I.
getWidth();
912 FilterType result =
static_cast<FilterType
>(0.);
914 for (
unsigned int i = 1; i <= stop; ++i) {
915 if ((c + i) < width) {
916 result += filter[i] *
static_cast<FilterType
>(I[r][c + i] + I[r][c - i]);
919 result += filter[i] *
static_cast<FilterType
>(I[r][2 * width - c - i - 1] + I[r][c - i]);
922 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
925 static inline double filterXRightBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
926 const double *filter,
unsigned int size)
928 const unsigned int stop = (size - 1) / 2;
929 const unsigned int width = I.
getWidth();
932 for (
unsigned int i = 1; i <= stop; ++i) {
933 if ((c + i) < width) {
934 result += filter[i] *
static_cast<double>(I[r][c + i].R + I[r][c - i].R);
937 result += filter[i] *
static_cast<double>(I[r][2 * width - c - i - 1].R + I[r][c - i].R);
940 return result + filter[0] *
static_cast<double>(I[r][c].R);
943 static inline double filterXRightBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
944 const double *filter,
unsigned int size)
946 const unsigned int stop = (size - 1) / 2;
947 const unsigned int width = I.
getWidth();
950 for (
unsigned int i = 1; i <= stop; ++i) {
951 if ((c + i) < width) {
952 result += filter[i] *
static_cast<double>(I[r][c + i].G + I[r][c - i].G);
955 result += filter[i] *
static_cast<double>(I[r][2 * width - c - i - 1].G + I[r][c - i].G);
958 return result + filter[0] *
static_cast<double>(I[r][c].G);
961 static inline double filterXRightBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
962 const double *filter,
unsigned int size)
964 const unsigned int stop = (size - 1) / 2;
965 const unsigned int width = I.
getWidth();
968 for (
unsigned int i = 1; i <= stop; ++i) {
969 if ((c + i) < width) {
970 result += filter[i] *
static_cast<double>(I[r][c + i].B + I[r][c - i].B);
973 result += filter[i] *
static_cast<double>(I[r][2 * width - c - i - 1].B + I[r][c - i].B);
976 return result + filter[0] *
static_cast<double>(I[r][c].B);
983 #ifndef DOXYGEN_SHOULD_SKIP_THIS
989 template<
typename ImageType,
typename FilterType>
994 const unsigned int stop1I = (size - 1) / 2;
995 const unsigned int stop2I = height - (size - 1) / 2;
996 resizeAndInitializeIfNeeded(p_mask, height, width, dIy);
998 for (
unsigned int i = 0; i < stop1I; ++i) {
999 for (
unsigned int j = 0; j < width; ++j) {
1002 bool computeVal = checkBooleanMask(p_mask, i, j);
1004 dIy[i][j] = vpImageFilter::filterYTopBorder<ImageType, FilterType>(I, i, j, filter, size);
1008 for (
unsigned int i = stop1I; i < stop2I; ++i) {
1009 for (
unsigned int j = 0; j < width; ++j) {
1012 bool computeVal = checkBooleanMask(p_mask, i, j);
1014 dIy[i][j] = vpImageFilter::filterY<ImageType, FilterType>(I, i, j, filter, size);
1018 for (
unsigned int i = stop2I; i < height; ++i) {
1019 for (
unsigned int j = 0; j < width; ++j) {
1022 bool computeVal = checkBooleanMask(p_mask, i, j);
1024 dIy[i][j] = vpImageFilter::filterYBottomBorder<ImageType, FilterType>(I, i, j, filter, size);
1030 template<
typename ImageType,
typename FilterType>
1033 const unsigned int stop = (size - 1) / 2;
1034 FilterType result =
static_cast<FilterType
>(0.);
1036 for (
unsigned int i = 1; i <= stop; ++i) {
1037 result += filter[i] *
static_cast<FilterType
>(I[r + i][c] + I[r - i][c]);
1039 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
1041 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1042 static inline double filterYR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1044 const unsigned int stop = (size - 1) / 2;
1047 for (
unsigned int i = 1; i <= stop; ++i) {
1048 result += filter[i] *
static_cast<double>(I[r + i][c].R + I[r - i][c].R);
1050 return result + filter[0] *
static_cast<double>(I[r][c].R);
1052 static inline double filterYG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1054 const unsigned int stop = (size - 1) / 2;
1057 for (
unsigned int i = 1; i <= stop; ++i) {
1058 result += filter[i] *
static_cast<double>(I[r + i][c].G + I[r - i][c].G);
1060 return result + filter[0] *
static_cast<double>(I[r][c].G);
1063 static inline double filterYB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1065 const unsigned int stop = (size - 1) / 2;
1068 for (
unsigned int i = 1; i <= stop; ++i) {
1069 result += filter[i] *
static_cast<double>(I[r + i][c].B + I[r - i][c].B);
1071 return result + filter[0] *
static_cast<double>(I[r][c].B);
1074 template<
typename ImageType,
typename FilterType>
1075 static inline FilterType filterYTopBorder(
const vpImage<ImageType> &I,
unsigned int r,
unsigned int c,
1076 const FilterType *filter,
unsigned int size)
1078 const unsigned int stop = (size - 1) / 2;
1079 FilterType result =
static_cast<FilterType
>(0.);
1081 for (
unsigned int i = 1; i <= stop; ++i) {
1083 result += filter[i] *
static_cast<FilterType
>(I[r + i][c] + I[r - i][c]);
1086 result += filter[i] *
static_cast<FilterType
>(I[r + i][c] + I[i - r][c]);
1089 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
1092 double static inline filterYTopBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1094 const unsigned int stop = (size - 1) / 2;
1097 for (
unsigned int i = 1; i <= stop; ++i) {
1099 result += filter[i] *
static_cast<double>(I[r + i][c].R + I[r - i][c].R);
1102 result += filter[i] *
static_cast<double>(I[r + i][c].R + I[i - r][c].R);
1105 return result + filter[0] *
static_cast<double>(I[r][c].R);
1108 double static inline filterYTopBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1110 const unsigned int stop = (size - 1) / 2;
1113 for (
unsigned int i = 1; i <= stop; ++i) {
1115 result += filter[i] *
static_cast<double>(I[r + i][c].G + I[r - i][c].G);
1118 result += filter[i] *
static_cast<double>(I[r + i][c].G + I[i - r][c].G);
1121 return result + filter[0] *
static_cast<double>(I[r][c].G);
1124 double static inline filterYTopBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
unsigned int size)
1126 const unsigned int stop = (size - 1) / 2;
1129 for (
unsigned int i = 1; i <= stop; ++i) {
1131 result += filter[i] *
static_cast<double>(I[r + i][c].B + I[r - i][c].B);
1134 result += filter[i] *
static_cast<double>(I[r + i][c].B + I[i - r][c].B);
1137 return result + filter[0] *
static_cast<double>(I[r][c].B);
1140 template<
typename ImageType,
typename FilterType>
1141 static inline FilterType filterYBottomBorder(
const vpImage<ImageType> &I,
unsigned int r,
unsigned int c,
1142 const FilterType *filter,
unsigned int size)
1144 const unsigned int height = I.
getHeight();
1145 const unsigned int stop = (size - 1) / 2;
1146 FilterType result =
static_cast<FilterType
>(0.);
1148 for (
unsigned int i = 1; i <= stop; ++i) {
1149 if ((r + i) < height) {
1150 result += filter[i] *
static_cast<FilterType
>(I[r + i][c] + I[r - i][c]);
1153 result += filter[i] *
static_cast<FilterType
>(I[2 * height - r - i - 1][c] + I[r - i][c]);
1156 return result + filter[0] *
static_cast<FilterType
>(I[r][c]);
1159 double static inline filterYBottomBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
1160 const double *filter,
unsigned int size)
1162 const unsigned int height = I.
getHeight();
1163 const unsigned int stop = (size - 1) / 2;
1166 for (
unsigned int i = 1; i <= stop; ++i) {
1167 if ((r + i) < height) {
1168 result += filter[i] *
static_cast<double>(I[r + i][c].R + I[r - i][c].R);
1171 result += filter[i] *
static_cast<double>(I[2 * height - r - i - 1][c].R + I[r - i][c].R);
1174 return result + filter[0] *
static_cast<double>(I[r][c].R);
1177 double static inline filterYBottomBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
1178 const double *filter,
unsigned int size)
1180 const unsigned int height = I.
getHeight();
1181 const unsigned int stop = (size - 1) / 2;
1184 for (
unsigned int i = 1; i <= stop; ++i) {
1185 if ((r + i) < height) {
1186 result += filter[i] *
static_cast<double>(I[r + i][c].G + I[r - i][c].G);
1189 result += filter[i] *
static_cast<double>(I[2 * height - r - i - 1][c].G + I[r - i][c].G);
1192 return result + filter[0] *
static_cast<double>(I[r][c].G);
1195 double static inline filterYBottomBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
1196 const double *filter,
unsigned int size)
1198 const unsigned int height = I.
getHeight();
1199 const unsigned int stop = (size - 1) / 2;
1202 for (
unsigned int i = 1; i <= stop; ++i) {
1203 if ((r + i) < height) {
1204 result += filter[i] *
static_cast<double>(I[r + i][c].B + I[r - i][c].B);
1207 result += filter[i] *
static_cast<double>(I[2 * height - r - i - 1][c].B + I[r - i][c].B);
1210 return result + filter[0] *
static_cast<double>(I[r][c].B);
1228 template <
typename ImageType,
typename FilterType>
1232 FilterType *fg =
new FilterType[(size + 1) / 2];
1233 vpImageFilter::getGaussianKernel<FilterType>(fg, size, sigma, normalize);
1235 vpImageFilter::filterX<ImageType, FilterType>(I, GIx, fg, size, p_mask);
1236 vpImageFilter::filterY<FilterType, FilterType>(GIx, GI, fg, size, p_mask);
1253 return (15.0 * fr[r][c] + 12.0 * (fr[r - 1][c] + fr[r][c - 1] + fr[r + 1][c] + fr[r][c + 1]) +
1254 9.0 * (fr[r - 1][c - 1] + fr[r + 1][c - 1] + fr[r - 1][c + 1] + fr[r + 1][c + 1]) +
1255 5.0 * (fr[r - 2][c] + fr[r][c - 2] + fr[r + 2][c] + fr[r][c + 2]) +
1256 4.0 * (fr[r - 2][c + 1] + fr[r - 2][c - 1] + fr[r - 1][c - 2] + fr[r + 1][c - 2] + fr[r + 2][c - 1] +
1257 fr[r + 2][c + 1] + fr[r - 1][c + 2] + fr[r + 1][c + 2]) +
1258 2.0 * (fr[r - 2][c - 2] + fr[r + 2][c - 2] + fr[r - 2][c + 2] + fr[r + 2][c + 2])) / 159.0;
1281 template<
typename FilterType>
1282 static void getGaussianKernel(FilterType *filter,
unsigned int size, FilterType sigma = 0.,
bool normalize =
true)
1284 if ((size % 2) != 1) {
1289 sigma =
static_cast<FilterType
>((size - 1) / 6.0);
1292 int middle = (
static_cast<int>(size) - 1) / 2;
1293 FilterType sigma2 =
static_cast<FilterType
>(
vpMath::sqr(sigma));
1294 FilterType coef1 =
static_cast<FilterType
>(1. / (sigma * sqrt(2. * M_PI)));
1295 FilterType _2_sigma2 =
static_cast<FilterType
>(2. * sigma2);
1296 for (
int i = 0; i <= middle; ++i) {
1297 filter[i] = coef1 *
static_cast<FilterType
>(exp(-(i * i) / _2_sigma2));
1302 for (
int i = 1; i <= middle; ++i) {
1303 sum += 2 * filter[i];
1307 for (
int i = 0; i <= middle; ++i) {
1308 filter[i] = filter[i] / sum;
1327 template <
typename FilterType>
1330 if ((size % 2) != 1) {
1335 sigma =
static_cast<FilterType
>((size - 1) / 6.0);
1338 int middle = (
static_cast<int>(size) - 1) / 2;
1339 FilterType sigma2 =
static_cast<FilterType
>(
vpMath::sqr(sigma));
1340 FilterType coef_1 =
static_cast<FilterType
>(1. / (sigma * sqrt(2. * M_PI)));
1341 FilterType coef_1_over_2 = coef_1 /
static_cast<FilterType
>(2.);
1342 FilterType _2_coef_1 =
static_cast<FilterType
>(2.) * coef_1;
1343 FilterType _2_sigma2 =
static_cast<FilterType
>(2. * sigma2);
1345 for (
int i = 1; i <= middle; ++i) {
1346 filter[i] = -coef_1_over_2 * (
static_cast<FilterType
>(exp(-((i + 1) * (i + 1)) / _2_sigma2)) -
static_cast<FilterType
>(exp(-((i - 1) * (i - 1)) / _2_sigma2)));
1351 for (
int i = 1; i <= middle; ++i) {
1352 sum += _2_coef_1 *
static_cast<FilterType
>(exp(-(i * i) / _2_sigma2));
1356 for (
int i = 1; i <= middle; ++i) {
1357 filter[i] = filter[i] / sum;
1363 template<
typename FilterType>
1367 const unsigned int stopJ = width - 3;
1368 resizeAndInitializeIfNeeded(p_mask, height, width, dIx);
1370 for (
unsigned int i = 0; i < height; ++i) {
1371 for (
unsigned int j = 0; j < 3; ++j) {
1373 bool computeVal = (p_mask ==
nullptr);
1375 dIx[i][j] =
static_cast<FilterType
>(0);
1378 for (
unsigned int j = 3; j < stopJ; ++j) {
1381 bool computeVal = checkBooleanMask(p_mask, i, j);
1386 for (
unsigned int j = stopJ; j < width; ++j) {
1388 bool computeVal = (p_mask ==
nullptr);
1390 dIx[i][j] =
static_cast<FilterType
>(0);
1396 template <
typename ImageType,
typename FilterType>
1400 const unsigned int stop1J = (size - 1) / 2;
1401 const unsigned int stop2J = width - (size - 1) / 2;
1402 resizeAndInitializeIfNeeded(p_mask, height, width, dIx);
1404 for (
unsigned int i = 0; i < height; ++i) {
1405 for (
unsigned int j = 0; j < stop1J; ++j) {
1407 bool computeVal = (p_mask ==
nullptr);
1409 dIx[i][j] =
static_cast<FilterType
>(0);
1412 for (
unsigned int j = stop1J; j < stop2J; ++j) {
1415 bool computeVal = checkBooleanMask(p_mask, i, j);
1417 dIx[i][j] = vpImageFilter::derivativeFilterX<ImageType, FilterType>(I, i, j, filter, size);
1420 for (
unsigned int j = stop2J; j < width; ++j) {
1422 bool computeVal = (p_mask ==
nullptr);
1424 dIx[i][j] =
static_cast<FilterType
>(0);
1441 template <
typename ImageType,
typename FilterType>
1443 const FilterType *gaussianDerivativeKernel,
unsigned int size,
const vpImage<bool> *p_mask =
nullptr)
1446 vpImageFilter::filterY<ImageType, FilterType>(I, GIy, gaussianKernel, size, p_mask);
1447 vpImageFilter::getGradX<FilterType, FilterType>(GIy, dIx, gaussianDerivativeKernel, size, p_mask);
1451 template <
typename FilterType>
1455 const unsigned int stopI = height - 3;
1456 resizeAndInitializeIfNeeded(p_mask, height, width, dIy);
1458 for (
unsigned int i = 0; i < 3; ++i) {
1459 for (
unsigned int j = 0; j < width; ++j) {
1462 bool computeVal = checkBooleanMask(p_mask, i, j);
1464 dIy[i][j] =
static_cast<FilterType
>(0);
1468 for (
unsigned int i = 3; i < stopI; ++i) {
1469 for (
unsigned int j = 0; j < width; ++j) {
1472 bool computeVal = checkBooleanMask(p_mask, i, j);
1478 for (
unsigned int i = stopI; i < height; ++i) {
1479 for (
unsigned int j = 0; j < width; ++j) {
1482 bool computeVal = checkBooleanMask(p_mask, i, j);
1484 dIy[i][j] =
static_cast<FilterType
>(0);
1490 template <
typename ImageType,
typename FilterType>
1494 const unsigned int stop1I = (size - 1) / 2;
1495 const unsigned int stop2I = height - (size - 1) / 2;
1496 resizeAndInitializeIfNeeded(p_mask, height, width, dIy);
1498 for (
unsigned int i = 0; i < stop1I; ++i) {
1499 for (
unsigned int j = 0; j < width; ++j) {
1502 bool computeVal = checkBooleanMask(p_mask, i, j);
1504 dIy[i][j] =
static_cast<FilterType
>(0);
1508 for (
unsigned int i = stop1I; i < stop2I; ++i) {
1509 for (
unsigned int j = 0; j < width; ++j) {
1512 bool computeVal = checkBooleanMask(p_mask, i, j);
1514 dIy[i][j] = vpImageFilter::derivativeFilterY<ImageType, FilterType>(I, i, j, filter, size);
1518 for (
unsigned int i = stop2I; i < height; ++i) {
1519 for (
unsigned int j = 0; j < width; ++j) {
1522 bool computeVal = checkBooleanMask(p_mask, i, j);
1524 dIy[i][j] =
static_cast<FilterType
>(0);
1541 template <
typename ImageType,
typename FilterType>
1543 const FilterType *gaussianDerivativeKernel,
unsigned int size,
const vpImage<bool> *p_mask =
nullptr)
1546 vpImageFilter::filterX<ImageType, FilterType>(I, GIx, gaussianKernel, size, p_mask);
1547 vpImageFilter::getGradY<FilterType, FilterType>(GIx, dIy, gaussianDerivativeKernel, size, p_mask);
1557 template <
typename FilterType>
1562 std::stringstream errMsg;
1563 errMsg <<
"Cannot get Scharr kernel of size " << size * 2 + 1 <<
" != 3";
1568 FilterType norm = getScharrKernelY<FilterType>(ScharrY.
data, size);
1569 memcpy(filter, ScharrY.
t().data, ScharrY.
getRows() * ScharrY.
getCols() *
sizeof(FilterType));
1580 template <
typename FilterType>
1584 static const FilterType ScharrY3x3[9] = { -3.0, -10.0, -3.0, 0.0, 0.0, 0.0, 3.0, 10.0, 3.0 };
1588 std::stringstream errMsg;
1589 errMsg <<
"Cannot get Scharr kernel of size " << size * 2 + 1 <<
" != 3";
1593 const unsigned int kernel_size = size * 2 + 1;
1594 if (kernel_size == 3) {
1595 memcpy(filter, ScharrY3x3, kernel_size * kernel_size *
sizeof(FilterType));
1596 return static_cast<FilterType
>(1.0 / 32.0);
1599 return static_cast<FilterType
>(0.);
1609 template <
typename FilterType>
1620 FilterType norm = getSobelKernelY<FilterType>(SobelY.
data, size);
1621 memcpy(filter, SobelY.
t().data, SobelY.
getRows() * SobelY.
getCols() *
sizeof(FilterType));
1632 template <
typename FilterType>
1636 static const FilterType SobelY3x3[9] = { -1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0 };
1637 static const FilterType SobelY5x5[25] = { -1.0, -4.0, -6.0, -4.0, -1.0, -2.0, -8.0, -12.0, -8.0, -2.0, 0.0, 0.0, 0.0,
1638 0.0, 0.0, 2.0, 8.0, 12.0, 8.0, 2.0, 1.0, 4.0, 6.0, 4.0, 1.0 };
1639 static const FilterType SobelY7x7[49] = { -1, -6, -15, -20, -15, -6, -1, -4, -24, -60, -80, -60, -24, -4, -5, -30, -75,
1640 -100, -75, -30, -5, 0, 0, 0, 0, 0, 0, 0, 5, 30, 75, 100, 75, 30,
1641 5, 4, 24, 60, 80, 60, 24, 4, 1, 6, 15, 20, 15, 6, 1 };
1643 smoothingKernel[0][0] = 1.0;
1644 smoothingKernel[0][1] = 2.0;
1645 smoothingKernel[0][2] = 1.0;
1646 smoothingKernel[1][0] = 2.0;
1647 smoothingKernel[1][1] = 4.0;
1648 smoothingKernel[1][2] = 2.0;
1649 smoothingKernel[2][0] = 1.0;
1650 smoothingKernel[2][1] = 2.0;
1651 smoothingKernel[2][2] = 1.0;
1660 const unsigned int kernel_size = size * 2 + 1;
1661 FilterType scale =
static_cast<FilterType
>(1. / 8.);
1662 if (kernel_size == 3) {
1663 memcpy(filter, SobelY3x3, kernel_size * kernel_size *
sizeof(FilterType));
1666 scale *=
static_cast<FilterType
>(1. / 16.);
1667 if (kernel_size == 5) {
1668 memcpy(filter, SobelY5x5, kernel_size * kernel_size *
sizeof(FilterType));
1671 scale *=
static_cast<FilterType
>(1. / 16.);
1672 if (kernel_size == 7) {
1673 memcpy(filter, SobelY7x7, kernel_size * kernel_size *
sizeof(FilterType));
1678 memcpy(sobelY.
data, SobelY7x7, sobelY.
getRows() * sobelY.
getCols() *
sizeof(FilterType));
1679 for (
unsigned int i = 4; i <= size; ++i) {
1682 scale *=
static_cast<FilterType
>(1. / 16.);
1685 memcpy(filter, sobelY.
data, sobelY.
getRows() * sobelY.
getCols() *
sizeof(FilterType));
1690 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
1691 static float median(
const cv::Mat &cv_I);
Implementation of a generic 2D array used as base class for matrices and vectors.
unsigned int getCols() const
Type * data
Address of the first element of the data array.
static vpArray2D< Type > conv2(const vpArray2D< Type > &M, const vpArray2D< Type > &kernel, const std::string &mode)
vpArray2D< Type > t() const
Compute the transpose of the array.
unsigned int getRows() const
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ dimensionError
Bad dimension.
@ notImplementedError
Not implemented.
Class to compute a gray level image histogram.
unsigned int getTotal()
Get the total number of pixels in the input image.
void calculate(const vpImage< unsigned char > &I, unsigned int nbins=256, unsigned int nbThreads=1)
void setMask(const vpImage< bool > *p_mask)
Set a mask to ignore pixels for which the mask is false.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
@ incorrectInitializationError
Wrong image initialization.
Various image filter, convolution, etc...
static void filterY(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void getGradY(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static FilterType filterX(const vpImage< ImageType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double derivativeFilterX(const vpImage< ImageType > &I, unsigned int r, unsigned int c)
static void computePartialDerivatives(const vpImage< vpRGBa > &I, vpImage< FilterType > &dIx, vpImage< FilterType > &dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int &gaussianKernelSize=5, const FilterType &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING, const vpCannyBackendType &backend=CANNY_VISP_BACKEND, const vpImage< bool > *p_mask=nullptr)
static void getGradX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx, const vpImage< bool > *p_mask=nullptr)
static float computeCannyThreshold(const vpImage< unsigned char > &I, float &lowerThresh, const vpImage< OutType > *p_dIx=nullptr, const vpImage< OutType > *p_dIy=nullptr, const unsigned int &gaussianKernelSize=5, const OutType &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const float &lowerThresholdRatio=0.6, const float &upperThresholdRatio=0.8, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING, const vpImage< bool > *p_mask=nullptr)
Compute the upper Canny edge filter threshold, using Gaussian blur + Sobel or + Scharr operators to c...
static FilterType getSobelKernelX(FilterType *filter, unsigned int size)
static void getGradXGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static void filterXB(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static FilterType filterY(const vpImage< ImageType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
vpCannyFilteringAndGradientType
Canny filter and gradient operators to apply on the image before the edge detection stage.
static void getGaussianDerivativeKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static void gaussianBlur(const vpImage< ImageType > &I, vpImage< FilterType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true, const vpImage< bool > *p_mask=nullptr)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false, const vpImage< bool > *p_mask=nullptr)
vpCannyBackendType
Canny filter backends for the edge detection operations.
@ CANNY_VISP_BACKEND
Use ViSP.
static void getGradX(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static FilterType derivativeFilterY(const vpImage< ImageType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static void filterXR(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static double derivativeFilterY(const vpImage< ImageType > &I, unsigned int r, unsigned int c)
static void getGaussianKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static void computePartialDerivatives(const vpImage< ImageType > &I, vpImage< unsigned char > &dIx, vpImage< unsigned char > &dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int &gaussianKernelSize=5, const unsigned char &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING, const vpCannyBackendType &backend=CANNY_VISP_BACKEND, const vpImage< bool > *p_mask=nullptr)
static FilterType getScharrKernelY(FilterType *filter, unsigned int size)
static void filter(const vpImage< vpRGBa > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false)
static void computePartialDerivatives(const vpImage< ImageType > &I, vpImage< vpRGBa > &dIx, vpImage< vpRGBa > &dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int gaussianKernelSize=5, const vpRGBa gaussianStdev=vpRGBa(), const unsigned int apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING, const vpCannyBackendType &backend=CANNY_VISP_BACKEND, const vpImage< bool > *p_mask=nullptr)
static FilterType getSobelKernelY(FilterType *filter, unsigned int size)
static void filter(const vpImage< vpRGBa > &I, vpImage< FilterType > &Iu, vpImage< FilterType > &Iv, const vpArray2D< FilterType > &M, bool convolve)
static void getGradYGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static FilterType getScharrKernelX(FilterType *filter, unsigned int size)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &GI, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static void filterXG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void getGradY(const vpImage< unsigned char > &I, vpImage< FilterType > &dIy, const vpImage< bool > *p_mask=nullptr)
static void filter(const vpImage< ImageType > &I, vpImage< ImageType > &Iu, vpImage< ImageType > &Iv, const vpArray2D< vpRGBa > &M, bool convolve)
static void filterX(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static void computePartialDerivatives(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, vpImage< FilterType > &dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int &gaussianKernelSize=5, const FilterType &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING, const vpCannyBackendType &backend=CANNY_VISP_BACKEND, const vpImage< bool > *p_mask=nullptr)
Compute the partial derivatives (i.e. horizontal and vertical gradients) of the input image.
static unsigned char filterGaussYPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &Iu, vpImage< FilterType > &Iv, const vpArray2D< FilterType > &M, bool convolve=false, const vpImage< bool > *p_mask=nullptr)
static double gaussianFilter(const vpImage< T > &fr, unsigned int r, unsigned int c)
static FilterType derivativeFilterX(const vpImage< ImageType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
void destroy()
Destructor : Memory de-allocation.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getHeight() const
static double sqr(double x)