39 #ifndef vpImageFilter_H
40 #define vpImageFilter_H
48 #include <visp3/core/vpImage.h>
49 #include <visp3/core/vpImageException.h>
50 #include <visp3/core/vpMath.h>
51 #include <visp3/core/vpMatrix.h>
52 #include <visp3/core/vpRGBa.h>
70 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)
72 double thresholdCanny,
unsigned int apertureSobel);
82 template <
class T>
static double derivativeFilterX(
const vpImage<T> &I,
unsigned int r,
unsigned int c)
84 return (2047.0 * (I[r][c + 1] - I[r][c - 1]) + 913.0 * (I[r][c + 2] - I[r][c - 2]) +
85 112.0 * (I[r][c + 3] - I[r][c - 3])) /
96 template <
class T>
static double derivativeFilterY(
const vpImage<T> &I,
unsigned int r,
unsigned int c)
98 return (2047.0 * (I[r + 1][c] - I[r - 1][c]) + 913.0 * (I[r + 2][c] - I[r - 2][c]) +
99 112.0 * (I[r + 3][c] - I[r - 3][c])) /
117 static double derivativeFilterX(
const vpImage<T> &I,
unsigned int r,
unsigned int c,
const double *filter,
125 for (i = 1; i <= (size - 1) / 2; i++) {
126 result += filter[i] * (I[r][c + i] - I[r][c - i]);
144 static double derivativeFilterY(
const vpImage<T> &I,
unsigned int r,
unsigned int c,
const double *filter,
152 for (i = 1; i <= (size - 1) / 2; i++) {
153 result += filter[i] * (I[r + i][c] - I[r - i][c]);
159 bool convolve =
false);
162 bool convolve =
false);
170 static inline unsigned char filterGaussXPyramidal(
const vpImage<unsigned char> &I,
unsigned int i,
unsigned int j)
172 return (
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]) /
175 static inline unsigned char filterGaussYPyramidal(
const vpImage<unsigned char> &I,
unsigned int i,
unsigned int j)
177 return (
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]) /
188 static inline double filterX(
const vpImage<unsigned char> &I,
unsigned int r,
unsigned int c,
const double *filter,
195 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
196 result += filter[i] * (I[r][c + i] + I[r][c - i]);
198 return result + filter[0] * I[r][c];
201 static inline double filterXR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
208 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
209 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
211 return result + filter[0] * I[r][c].R;
214 static inline double filterXG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
221 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
222 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
224 return result + filter[0] * I[r][c].G;
227 static inline double filterXB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
234 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
235 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
237 return result + filter[0] * I[r][c].B;
241 const double *filter,
unsigned int size)
247 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
249 result += filter[i] * (I[r][c + i] + I[r][c - i]);
251 result += filter[i] * (I[r][c + i] + I[r][i - c]);
253 return result + filter[0] * I[r][c];
256 static inline double filterXLeftBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
257 const double *filter,
unsigned int size)
263 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
265 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
267 result += filter[i] * (I[r][c + i].R + I[r][i - c].R);
269 return result + filter[0] * I[r][c].R;
272 static inline double filterXLeftBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
273 const double *filter,
unsigned int size)
279 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
281 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
283 result += filter[i] * (I[r][c + i].G + I[r][i - c].G);
285 return result + filter[0] * I[r][c].G;
288 static inline double filterXLeftBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
289 const double *filter,
unsigned int size)
295 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
297 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
299 result += filter[i] * (I[r][c + i].B + I[r][i - c].B);
301 return result + filter[0] * I[r][c].B;
305 const double *filter,
unsigned int size)
311 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
313 result += filter[i] * (I[r][c + i] + I[r][c - i]);
315 result += filter[i] * (I[r][2 * I.
getWidth() - c - i - 1] + I[r][c - i]);
317 return result + filter[0] * I[r][c];
320 static inline double filterXRightBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
321 const double *filter,
unsigned int size)
327 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
329 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
331 result += filter[i] * (I[r][2 * I.
getWidth() - c - i - 1].R + I[r][c - i].R);
333 return result + filter[0] * I[r][c].R;
336 static inline double filterXRightBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
337 const double *filter,
unsigned int size)
343 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
345 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
347 result += filter[i] * (I[r][2 * I.
getWidth() - c - i - 1].G + I[r][c - i].G);
349 return result + filter[0] * I[r][c].G;
352 static inline double filterXRightBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
353 const double *filter,
unsigned int size)
359 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
361 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
363 result += filter[i] * (I[r][2 * I.
getWidth() - c - i - 1].B + I[r][c - i].B);
365 return result + filter[0] * I[r][c].B;
368 static inline double filterX(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
const double *filter,
375 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
376 result += filter[i] * (I[r][c + i] + I[r][c - i]);
378 return result + filter[0] * I[r][c];
381 static inline double filterXLeftBorder(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
const double *filter,
388 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
390 result += filter[i] * (I[r][c + i] + I[r][c - i]);
392 result += filter[i] * (I[r][c + i] + I[r][i - c]);
394 return result + filter[0] * I[r][c];
397 static inline double filterXRightBorder(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
398 const double *filter,
unsigned int size)
404 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
406 result += filter[i] * (I[r][c + i] + I[r][c - i]);
408 result += filter[i] * (I[r][2 * I.
getWidth() - c - i - 1] + I[r][c - i]);
410 return result + filter[0] * I[r][c];
419 static inline double filterY(
const vpImage<unsigned char> &I,
unsigned int r,
unsigned int c,
const double *filter,
426 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
427 result += filter[i] * (I[r + i][c] + I[r - i][c]);
429 return result + filter[0] * I[r][c];
432 static inline double filterYR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
439 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
440 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
442 return result + filter[0] * I[r][c].R;
444 static inline double filterYG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
451 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
452 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
454 return result + filter[0] * I[r][c].G;
456 static inline double filterYB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
const double *filter,
463 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
464 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
466 return result + filter[0] * I[r][c].B;
470 const double *filter,
unsigned int size)
476 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
478 result += filter[i] * (I[r + i][c] + I[r - i][c]);
480 result += filter[i] * (I[r + i][c] + I[i - r][c]);
482 return result + filter[0] * I[r][c];
485 double static inline filterYTopBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
486 const double *filter,
unsigned int size)
492 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
494 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
496 result += filter[i] * (I[r + i][c].R + I[i - r][c].R);
498 return result + filter[0] * I[r][c].R;
501 double static inline filterYTopBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
502 const double *filter,
unsigned int size)
508 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
510 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
512 result += filter[i] * (I[r + i][c].G + I[i - r][c].G);
514 return result + filter[0] * I[r][c].G;
517 double static inline filterYTopBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
518 const double *filter,
unsigned int size)
524 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
526 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
528 result += filter[i] * (I[r + i][c].B + I[i - r][c].B);
530 return result + filter[0] * I[r][c].B;
534 const double *filter,
unsigned int size)
540 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
542 result += filter[i] * (I[r + i][c] + I[r - i][c]);
544 result += filter[i] * (I[2 * I.
getHeight() - r - i - 1][c] + I[r - i][c]);
546 return result + filter[0] * I[r][c];
549 double static inline filterYBottomBorderR(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
550 const double *filter,
unsigned int size)
556 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
558 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
560 result += filter[i] * (I[2 * I.
getHeight() - r - i - 1][c].R + I[r - i][c].R);
562 return result + filter[0] * I[r][c].R;
565 double static inline filterYBottomBorderG(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
566 const double *filter,
unsigned int size)
572 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
574 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
576 result += filter[i] * (I[2 * I.
getHeight() - r - i - 1][c].G + I[r - i][c].G);
578 return result + filter[0] * I[r][c].G;
581 double static inline filterYBottomBorderB(
const vpImage<vpRGBa> &I,
unsigned int r,
unsigned int c,
582 const double *filter,
unsigned int size)
588 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
590 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
592 result += filter[i] * (I[2 * I.
getHeight() - r - i - 1][c].B + I[r - i][c].B);
594 return result + filter[0] * I[r][c].B;
597 static inline double filterYTopBorder(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
const double *filter,
604 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
606 result += filter[i] * (I[r + i][c] + I[r - i][c]);
608 result += filter[i] * (I[r + i][c] + I[i - r][c]);
610 return result + filter[0] * I[r][c];
613 static inline double filterYBottomBorder(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
614 const double *filter,
unsigned int size)
620 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
622 result += filter[i] * (I[r + i][c] + I[r - i][c]);
624 result += filter[i] * (I[2 * I.
getHeight() - r - i - 1][c] + I[r - i][c]);
626 return result + filter[0] * I[r][c];
629 static inline double filterY(
const vpImage<double> &I,
unsigned int r,
unsigned int c,
const double *filter,
636 for (
unsigned int i = 1; i <= (size - 1) / 2; i++) {
637 result += filter[i] * (I[r + i][c] + I[r - i][c]);
639 return result + filter[0] * I[r][c];
643 double sigma = 0.,
bool normalize =
true);
645 double sigma = 0.,
bool normalize =
true);
647 bool normalize =
true);
655 template <
class T>
static double gaussianFilter(
const vpImage<T> &fr,
unsigned int r,
unsigned int c)
658 return (15.0 * fr[r][c] + 12.0 * (fr[r - 1][c] + fr[r][c - 1] + fr[r + 1][c] + fr[r][c + 1]) +
659 9.0 * (fr[r - 1][c - 1] + fr[r + 1][c - 1] + fr[r - 1][c + 1] + fr[r + 1][c + 1]) +
660 5.0 * (fr[r - 2][c] + fr[r][c - 2] + fr[r + 2][c] + fr[r][c + 2]) +
661 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] +
662 fr[r + 2][c + 1] + fr[r - 1][c + 2] + fr[r + 1][c + 2]) +
663 2.0 * (fr[r - 2][c - 2] + fr[r + 2][c - 2] + fr[r - 2][c + 2] + fr[r + 2][c + 2])) /
671 static void getGaussianKernel(
double *filter,
unsigned int size,
double sigma = 0.,
bool normalize =
true);
672 static void getGaussianDerivativeKernel(
double *filter,
unsigned int size,
double sigma = 0.,
bool normalize =
true);
680 const double *gaussianDerivativeKernel,
unsigned int size);
687 const double *gaussianDerivativeKernel,
unsigned int size);
689 static double getSobelKernelX(
double *filter,
unsigned int size);
690 static double getSobelKernelY(
double *filter,
unsigned int size);