Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpImageFilter.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Various image tools, convolution, ...
32 */
33
34#ifndef _vpImageFilter_h_
35#define _vpImageFilter_h_
36
43#include <fstream>
44#include <iostream>
45#include <math.h>
46#include <string.h>
47
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>
53
54#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
55#include <opencv2/imgproc/imgproc.hpp>
56#include <opencv2/imgproc/imgproc_c.h>
57#endif
58
67class VISP_EXPORT vpImageFilter
68{
69public:
70 static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, unsigned int gaussianFilterSize,
71 float thresholdCanny, unsigned int apertureSobel);
72
73 static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, unsigned int gaussianFilterSize,
74 float lowerThresholdCanny, float higherThresholdCanny, unsigned int apertureSobel);
75
83 template <class T> static double derivativeFilterX(const vpImage<T> &I, unsigned int r, unsigned int c)
84 {
85 return (2047.0 * (I[r][c + 1] - I[r][c - 1]) + 913.0 * (I[r][c + 2] - I[r][c - 2]) +
86 112.0 * (I[r][c + 3] - I[r][c - 3])) / 8418.0;
87 }
88
96 template <class T> static double derivativeFilterY(const vpImage<T> &I, unsigned int r, unsigned int c)
97 {
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])) / 8418.0;
100 }
101
115 template <class T, typename FilterType>
116 static FilterType derivativeFilterX(const vpImage<T> &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
117 {
118 unsigned int i;
119 FilterType result;
120
121 result = 0;
122
123 for (i = 1; i <= (size - 1) / 2; i++) {
124 result += filter[i] * (I[r][c + i] - I[r][c - i]);
125 }
126 return result;
127 }
128
142 template <class T, typename FilterType>
143 static FilterType derivativeFilterY(const vpImage<T> &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
144 {
145 unsigned int i;
146 FilterType result;
147
148 result = 0;
149
150 for (i = 1; i <= (size - 1) / 2; i++) {
151 result += filter[i] * (I[r + i][c] - I[r - i][c]);
152 }
153 return result;
154 }
155
184 template <typename FilterType>
185 static void filter(const vpImage<unsigned char> &I, vpImage<FilterType> &If, const vpArray2D<FilterType> &M, bool convolve = false)
186 {
187 unsigned int size_y = M.getRows(), size_x = M.getCols();
188 unsigned int half_size_y = size_y / 2, half_size_x = size_x / 2;
189
190 If.resize(I.getHeight(), I.getWidth(), 0.0);
191
192 if (convolve) {
193 for (unsigned int i = half_size_y; i < I.getHeight() - half_size_y; i++) {
194 for (unsigned int j = half_size_x; j < I.getWidth() - half_size_x; j++) {
195 FilterType conv = 0;
196
197 for (unsigned int a = 0; a < size_y; a++) {
198 for (unsigned int b = 0; b < size_x; b++) {
199 FilterType val = I[i + half_size_y - a][j + half_size_x - b]; // Convolution
200 conv += M[a][b] * val;
201 }
202 }
203 If[i][j] = conv;
204 }
205 }
206 }
207 else {
208 for (unsigned int i = half_size_y; i < I.getHeight() - half_size_y; i++) {
209 for (unsigned int j = half_size_x; j < I.getWidth() - half_size_x; j++) {
210 FilterType corr = 0;
211
212 for (unsigned int a = 0; a < size_y; a++) {
213 for (unsigned int b = 0; b < size_x; b++) {
214 FilterType val = I[i - half_size_y + a][j - half_size_x + b]; // Correlation
215 corr += M[a][b] * val;
216 }
217 }
218 If[i][j] = corr;
219 }
220 }
221 }
222 }
223
236 template <typename FilterType>
238 bool convolve = false)
239 {
240 unsigned int size = M.getRows();
241 unsigned int half_size = size / 2;
242
243 Iu.resize(I.getHeight(), I.getWidth(), 0.0);
244 Iv.resize(I.getHeight(), I.getWidth(), 0.0);
245
246 if (convolve) {
247 for (unsigned int v = half_size; v < I.getHeight() - half_size; v++) {
248 for (unsigned int u = half_size; u < I.getWidth() - half_size; u++) {
249 FilterType conv_u = 0;
250 FilterType conv_v = 0;
251
252 for (unsigned int a = 0; a < size; a++) {
253 for (unsigned int b = 0; b < size; b++) {
254 FilterType val = I[v + half_size - a][u + half_size - b]; // Convolution
255 conv_u += M[a][b] * val;
256 conv_v += M[b][a] * val;
257 }
258 }
259 Iu[v][u] = conv_u;
260 Iv[v][u] = conv_v;
261 }
262 }
263 }
264 else {
265 for (unsigned int v = half_size; v < I.getHeight() - half_size; v++) {
266 for (unsigned int u = half_size; u < I.getWidth() - half_size; u++) {
267 FilterType conv_u = 0;
268 FilterType conv_v = 0;
269
270 for (unsigned int a = 0; a < size; a++) {
271 for (unsigned int b = 0; b < size; b++) {
272 FilterType val = I[v - half_size + a][u - half_size + b]; // Correlation
273 conv_u += M[a][b] * val;
274 conv_v += M[b][a] * val;
275 }
276 }
277 Iu[v][u] = conv_u;
278 Iv[v][u] = conv_v;
279 }
280 }
281 }
282 }
283
284 static void sepFilter(const vpImage<unsigned char> &I, vpImage<double> &If, const vpColVector &kernelH, const vpColVector &kernelV);
285
294 template <typename FilterType>
295 static void filter(const vpImage<unsigned char> &I, vpImage<FilterType> &GI, const FilterType *filter, unsigned int size)
296 {
298 filterX<FilterType>(I, GIx, filter, size);
299 filterY<FilterType>(GIx, GI, filter, size);
300 GIx.destroy();
301 }
302
311 template <typename FilterType>
312 static void filter(const vpImage<FilterType> &I, vpImage<FilterType> &GI, const FilterType *filter, unsigned int size)
313 {
315 filterX<FilterType>(I, GIx, filter, size);
316 filterY<FilterType>(GIx, GI, filter, size);
317 GIx.destroy();
318 }
319
320 static inline unsigned char filterGaussXPyramidal(const vpImage<unsigned char> &I, unsigned int i, unsigned int j)
321 {
322 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]) / 16.);
323 }
324 static inline unsigned char filterGaussYPyramidal(const vpImage<unsigned char> &I, unsigned int i, unsigned int j)
325 {
326 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]) / 16.);
327 }
328
329 template <typename FilterType>
330 static void filterX(const vpImage<unsigned char> &I, vpImage<FilterType> &dIx, const FilterType *filter, unsigned int size)
331 {
332 dIx.resize(I.getHeight(), I.getWidth());
333 for (unsigned int i = 0; i < I.getHeight(); i++) {
334 for (unsigned int j = 0; j < (size - 1) / 2; j++) {
335 dIx[i][j] = vpImageFilter::filterXLeftBorder<FilterType>(I, i, j, filter, size);
336 }
337 for (unsigned int j = (size - 1) / 2; j < I.getWidth() - (size - 1) / 2; j++) {
338 dIx[i][j] = vpImageFilter::filterX<FilterType>(I, i, j, filter, size);
339 }
340 for (unsigned int j = I.getWidth() - (size - 1) / 2; j < I.getWidth(); j++) {
341 dIx[i][j] = vpImageFilter::filterXRightBorder<FilterType>(I, i, j, filter, size);
342 }
343 }
344 }
345
346 template<typename FilterType>
347 static void filterX(const vpImage<FilterType> &I, vpImage<FilterType> &dIx, const FilterType *filter, unsigned int size)
348 {
349 dIx.resize(I.getHeight(), I.getWidth());
350 for (unsigned int i = 0; i < I.getHeight(); i++) {
351 for (unsigned int j = 0; j < (size - 1) / 2; j++) {
352 dIx[i][j] = vpImageFilter::filterXLeftBorder<FilterType>(I, i, j, filter, size);
353 }
354 for (unsigned int j = (size - 1) / 2; j < I.getWidth() - (size - 1) / 2; j++) {
355 dIx[i][j] = vpImageFilter::filterX<FilterType>(I, i, j, filter, size);
356 }
357 for (unsigned int j = I.getWidth() - (size - 1) / 2; j < I.getWidth(); j++) {
358 dIx[i][j] = vpImageFilter::filterXRightBorder<FilterType>(I, i, j, filter, size);
359 }
360 }
361 }
362
363 static void filterX(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
364 static void filterXR(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
365 static void filterXG(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
366 static void filterXB(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
367
368 template<typename FilterType>
369 static inline FilterType filterX(const vpImage<unsigned char> &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
370 {
371 FilterType result;
372
373 result = 0;
374
375 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
376 result += filter[i] * (I[r][c + i] + I[r][c - i]);
377 }
378 return result + filter[0] * I[r][c];
379 }
380
381 static inline double filterXR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
382 {
383 double result;
384
385 result = 0;
386
387 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
388 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
389 }
390 return result + filter[0] * I[r][c].R;
391 }
392
393 static inline double filterXG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
394 {
395 double result;
396
397 result = 0;
398
399 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
400 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
401 }
402 return result + filter[0] * I[r][c].G;
403 }
404
405 static inline double filterXB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
406 {
407 double result;
408
409 result = 0;
410
411 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
412 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
413 }
414 return result + filter[0] * I[r][c].B;
415 }
416
417 template <typename FilterType>
418 static inline FilterType filterXLeftBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
419 const FilterType *filter, unsigned int size)
420 {
421 FilterType result;
422
423 result = 0;
424
425 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
426 if (c > i)
427 result += filter[i] * (I[r][c + i] + I[r][c - i]);
428 else
429 result += filter[i] * (I[r][c + i] + I[r][i - c]);
430 }
431 return result + filter[0] * I[r][c];
432 }
433
434 static inline double filterXLeftBorderR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
435 const double *filter, unsigned int size)
436 {
437 double result;
438
439 result = 0;
440
441 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
442 if (c > i)
443 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
444 else
445 result += filter[i] * (I[r][c + i].R + I[r][i - c].R);
446 }
447 return result + filter[0] * I[r][c].R;
448 }
449
450 static inline double filterXLeftBorderG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
451 const double *filter, unsigned int size)
452 {
453 double result;
454
455 result = 0;
456
457 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
458 if (c > i)
459 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
460 else
461 result += filter[i] * (I[r][c + i].G + I[r][i - c].G);
462 }
463 return result + filter[0] * I[r][c].G;
464 }
465
466 static inline double filterXLeftBorderB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
467 const double *filter, unsigned int size)
468 {
469 double result;
470
471 result = 0;
472
473 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
474 if (c > i)
475 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
476 else
477 result += filter[i] * (I[r][c + i].B + I[r][i - c].B);
478 }
479 return result + filter[0] * I[r][c].B;
480 }
481
482 template <typename FilterType>
483 static inline FilterType filterXRightBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
484 const FilterType *filter, unsigned int size)
485 {
486 FilterType result;
487
488 result = 0;
489
490 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
491 if (c + i < I.getWidth())
492 result += filter[i] * (I[r][c + i] + I[r][c - i]);
493 else
494 result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1] + I[r][c - i]);
495 }
496 return result + filter[0] * I[r][c];
497 }
498
499 static inline double filterXRightBorderR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
500 const double *filter, unsigned int size)
501 {
502 double result;
503
504 result = 0;
505
506 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
507 if (c + i < I.getWidth())
508 result += filter[i] * (I[r][c + i].R + I[r][c - i].R);
509 else
510 result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1].R + I[r][c - i].R);
511 }
512 return result + filter[0] * I[r][c].R;
513 }
514
515 static inline double filterXRightBorderG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
516 const double *filter, unsigned int size)
517 {
518 double result;
519
520 result = 0;
521
522 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
523 if (c + i < I.getWidth())
524 result += filter[i] * (I[r][c + i].G + I[r][c - i].G);
525 else
526 result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1].G + I[r][c - i].G);
527 }
528 return result + filter[0] * I[r][c].G;
529 }
530
531 static inline double filterXRightBorderB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
532 const double *filter, unsigned int size)
533 {
534 double result;
535
536 result = 0;
537
538 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
539 if (c + i < I.getWidth())
540 result += filter[i] * (I[r][c + i].B + I[r][c - i].B);
541 else
542 result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1].B + I[r][c - i].B);
543 }
544 return result + filter[0] * I[r][c].B;
545 }
546
547 template <typename FilterType>
548 static inline FilterType filterX(const vpImage<FilterType> &I, unsigned int r, unsigned int c,
549 const FilterType *filter, unsigned int size)
550 {
551 FilterType result;
552
553 result = 0;
554
555 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
556 result += filter[i] * (I[r][c + i] + I[r][c - i]);
557 }
558 return result + filter[0] * I[r][c];
559 }
560
561 template <typename FilterType>
562 static inline FilterType filterXLeftBorder(const vpImage<FilterType> &I, unsigned int r, unsigned int c,
563 const FilterType *filter, unsigned int size)
564 {
565 FilterType result;
566
567 result = 0;
568
569 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
570 if (c > i)
571 result += filter[i] * (I[r][c + i] + I[r][c - i]);
572 else
573 result += filter[i] * (I[r][c + i] + I[r][i - c]);
574 }
575 return result + filter[0] * I[r][c];
576 }
577
578 template <typename FilterType>
579 static inline FilterType filterXRightBorder(const vpImage<FilterType> &I, unsigned int r, unsigned int c,
580 const FilterType *filter, unsigned int size)
581 {
582 FilterType result;
583
584 result = 0;
585
586 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
587 if (c + i < I.getWidth())
588 result += filter[i] * (I[r][c + i] + I[r][c - i]);
589 else
590 result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1] + I[r][c - i]);
591 }
592 return result + filter[0] * I[r][c];
593 }
594
595 template <typename FilterType>
596 static void filterY(const vpImage<unsigned char> &I, vpImage<FilterType> &dIy, const FilterType *filter, unsigned int size)
597 {
598 dIy.resize(I.getHeight(), I.getWidth());
599 for (unsigned int i = 0; i < (size - 1) / 2; i++) {
600 for (unsigned int j = 0; j < I.getWidth(); j++) {
601 dIy[i][j] = vpImageFilter::filterYTopBorder<FilterType>(I, i, j, filter, size);
602 }
603 }
604 for (unsigned int i = (size - 1) / 2; i < I.getHeight() - (size - 1) / 2; i++) {
605 for (unsigned int j = 0; j < I.getWidth(); j++) {
606 dIy[i][j] = vpImageFilter::filterY<FilterType>(I, i, j, filter, size);
607 }
608 }
609 for (unsigned int i = I.getHeight() - (size - 1) / 2; i < I.getHeight(); i++) {
610 for (unsigned int j = 0; j < I.getWidth(); j++) {
611 dIy[i][j] = vpImageFilter::filterYBottomBorder<FilterType>(I, i, j, filter, size);
612 }
613 }
614 }
615
616 static void filterY(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
617 static void filterYR(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
618 static void filterYG(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
619 static void filterYB(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size);
620
621 template<typename FilterType>
622 static void filterY(const vpImage<FilterType> &I, vpImage<FilterType> &dIy, const FilterType *filter, unsigned int size)
623 {
624 dIy.resize(I.getHeight(), I.getWidth());
625 for (unsigned int i = 0; i < (size - 1) / 2; i++) {
626 for (unsigned int j = 0; j < I.getWidth(); j++) {
627 dIy[i][j] = vpImageFilter::filterYTopBorder<FilterType>(I, i, j, filter, size);
628 }
629 }
630 for (unsigned int i = (size - 1) / 2; i < I.getHeight() - (size - 1) / 2; i++) {
631 for (unsigned int j = 0; j < I.getWidth(); j++) {
632 dIy[i][j] = vpImageFilter::filterY<FilterType>(I, i, j, filter, size);
633 }
634 }
635 for (unsigned int i = I.getHeight() - (size - 1) / 2; i < I.getHeight(); i++) {
636 for (unsigned int j = 0; j < I.getWidth(); j++) {
637 dIy[i][j] = vpImageFilter::filterYBottomBorder<FilterType>(I, i, j, filter, size);
638 }
639 }
640 }
641
642 template<typename FilterType>
643 static inline FilterType filterY(const vpImage<unsigned char> &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
644 {
645 FilterType result;
646
647 result = 0;
648
649 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
650 result += filter[i] * (I[r + i][c] + I[r - i][c]);
651 }
652 return result + filter[0] * I[r][c];
653 }
654
655 static inline double filterYR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
656 {
657 double result;
658
659 result = 0;
660
661 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
662 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
663 }
664 return result + filter[0] * I[r][c].R;
665 }
666 static inline double filterYG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
667 {
668 double result;
669
670 result = 0;
671
672 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
673 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
674 }
675 return result + filter[0] * I[r][c].G;
676 }
677
678 static inline double filterYB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
679 {
680 double result;
681
682 result = 0;
683
684 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
685 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
686 }
687 return result + filter[0] * I[r][c].B;
688 }
689
690 template<typename FilterType>
691 static inline FilterType filterYTopBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
692 const FilterType *filter, unsigned int size)
693 {
694 FilterType result;
695
696 result = 0;
697
698 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
699 if (r > i)
700 result += filter[i] * (I[r + i][c] + I[r - i][c]);
701 else
702 result += filter[i] * (I[r + i][c] + I[i - r][c]);
703 }
704 return result + filter[0] * I[r][c];
705 }
706
707 double static inline filterYTopBorderR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
708 {
709 double result;
710
711 result = 0;
712
713 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
714 if (r > i)
715 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
716 else
717 result += filter[i] * (I[r + i][c].R + I[i - r][c].R);
718 }
719 return result + filter[0] * I[r][c].R;
720 }
721
722 double static inline filterYTopBorderG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
723 {
724 double result;
725
726 result = 0;
727
728 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
729 if (r > i)
730 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
731 else
732 result += filter[i] * (I[r + i][c].G + I[i - r][c].G);
733 }
734 return result + filter[0] * I[r][c].G;
735 }
736
737 double static inline filterYTopBorderB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
738 {
739 double result;
740
741 result = 0;
742
743 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
744 if (r > i)
745 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
746 else
747 result += filter[i] * (I[r + i][c].B + I[i - r][c].B);
748 }
749 return result + filter[0] * I[r][c].B;
750 }
751
752 template<typename FilterType>
753 static inline FilterType filterYBottomBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
754 const FilterType *filter, unsigned int size)
755 {
756 FilterType result;
757
758 result = 0;
759
760 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
761 if (r + i < I.getHeight())
762 result += filter[i] * (I[r + i][c] + I[r - i][c]);
763 else
764 result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c] + I[r - i][c]);
765 }
766 return result + filter[0] * I[r][c];
767 }
768
769 double static inline filterYBottomBorderR(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
770 const double *filter, unsigned int size)
771 {
772 double result;
773
774 result = 0;
775
776 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
777 if (r + i < I.getHeight())
778 result += filter[i] * (I[r + i][c].R + I[r - i][c].R);
779 else
780 result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c].R + I[r - i][c].R);
781 }
782 return result + filter[0] * I[r][c].R;
783 }
784
785 double static inline filterYBottomBorderG(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
786 const double *filter, unsigned int size)
787 {
788 double result;
789
790 result = 0;
791
792 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
793 if (r + i < I.getHeight())
794 result += filter[i] * (I[r + i][c].G + I[r - i][c].G);
795 else
796 result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c].G + I[r - i][c].G);
797 }
798 return result + filter[0] * I[r][c].G;
799 }
800
801 double static inline filterYBottomBorderB(const vpImage<vpRGBa> &I, unsigned int r, unsigned int c,
802 const double *filter, unsigned int size)
803 {
804 double result;
805
806 result = 0;
807
808 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
809 if (r + i < I.getHeight())
810 result += filter[i] * (I[r + i][c].B + I[r - i][c].B);
811 else
812 result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c].B + I[r - i][c].B);
813 }
814 return result + filter[0] * I[r][c].B;
815 }
816
817 template<typename FilterType>
818 static inline FilterType filterYTopBorder(const vpImage<double> &I, unsigned int r, unsigned int c,
819 const FilterType *filter, unsigned int size)
820 {
821 FilterType result;
822
823 result = 0;
824
825 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
826 if (r > i)
827 result += filter[i] * (I[r + i][c] + I[r - i][c]);
828 else
829 result += filter[i] * (I[r + i][c] + I[i - r][c]);
830 }
831 return result + filter[0] * I[r][c];
832 }
833
834 template<typename FilterType>
835 static inline FilterType filterYBottomBorder(const vpImage<double> &I, unsigned int r, unsigned int c,
836 const FilterType *filter, unsigned int size)
837 {
838 FilterType result;
839
840 result = 0;
841
842 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
843 if (r + i < I.getHeight())
844 result += filter[i] * (I[r + i][c] + I[r - i][c]);
845 else
846 result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c] + I[r - i][c]);
847 }
848 return result + filter[0] * I[r][c];
849 }
850
851 template<typename FilterType>
852 static inline FilterType filterY(const vpImage<double> &I, unsigned int r, unsigned int c,
853 const FilterType *filter, unsigned int size)
854 {
855 FilterType result;
856
857 result = 0;
858
859 for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
860 result += filter[i] * (I[r + i][c] + I[r - i][c]);
861 }
862 return result + filter[0] * I[r][c];
863 }
864
877 template <typename FilterType>
878 static void gaussianBlur(const vpImage<unsigned char> &I, vpImage<FilterType> &GI, unsigned int size = 7, FilterType sigma = 0., bool normalize = true)
879 {
880 FilterType *fg = new FilterType[(size + 1) / 2];
881 vpImageFilter::getGaussianKernel<FilterType>(fg, size, sigma, normalize);
883 vpImageFilter::filterX<FilterType>(I, GIx, fg, size);
884 vpImageFilter::filterY<FilterType>(GIx, GI, fg, size);
885 GIx.destroy();
886 delete[] fg;
887 }
888
889 static void gaussianBlur(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &GI, unsigned int size = 7, double sigma = 0., bool normalize = true);
890
903 template <typename FilterType>
904 static void gaussianBlur(const vpImage<FilterType> &I, vpImage<FilterType> &GI, unsigned int size = 7, FilterType sigma = 0., bool normalize = true)
905 {
906 FilterType *fg = new FilterType[(size + 1) / 2];
907 vpImageFilter::getGaussianKernel<FilterType>(fg, size, sigma, normalize);
909 vpImageFilter::filterX<FilterType>(I, GIx, fg, size);
910 vpImageFilter::filterY<FilterType>(GIx, GI, fg, size);
911 GIx.destroy();
912 delete[] fg;
913 }
914
922 template <class T> static double gaussianFilter(const vpImage<T> &fr, unsigned int r, unsigned int c)
923 {
924 return (15.0 * fr[r][c] + 12.0 * (fr[r - 1][c] + fr[r][c - 1] + fr[r + 1][c] + fr[r][c + 1]) +
925 9.0 * (fr[r - 1][c - 1] + fr[r + 1][c - 1] + fr[r - 1][c + 1] + fr[r + 1][c + 1]) +
926 5.0 * (fr[r - 2][c] + fr[r][c - 2] + fr[r + 2][c] + fr[r][c + 2]) +
927 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] +
928 fr[r + 2][c + 1] + fr[r - 1][c + 2] + fr[r + 1][c + 2]) +
929 2.0 * (fr[r - 2][c - 2] + fr[r + 2][c - 2] + fr[r - 2][c + 2] + fr[r + 2][c + 2])) / 159.0;
930 }
931 // Gaussian pyramid operation
932 static void getGaussPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
933 static void getGaussXPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
934 static void getGaussYPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
935
952 template<typename FilterType>
953 static void getGaussianKernel(FilterType *filter, unsigned int size, FilterType sigma = 0., bool normalize = true)
954 {
955 if (size % 2 != 1)
956 throw(vpImageException(vpImageException::incorrectInitializationError, "Bad Gaussian filter size"));
957
958 if (sigma <= 0)
959 sigma = static_cast<FilterType>((size - 1) / 6.0);
960
961 int middle = (int)(size - 1) / 2;
962 FilterType sigma2 = static_cast<FilterType>(vpMath::sqr(sigma));
963 FilterType coef1 = static_cast<FilterType>(1. / (sigma * sqrt(2. * M_PI)));
964 FilterType _2_sigma2 = static_cast<FilterType>(2. * sigma2);
965 for (int i = 0; i <= middle; i++) {
966 filter[i] = coef1 * exp(-(i * i) / _2_sigma2);
967 }
968 if (normalize) {
969 // renormalization
970 FilterType sum = 0;
971 for (int i = 1; i <= middle; i++) {
972 sum += 2 * filter[i];
973 }
974 sum += filter[0];
975
976 for (int i = 0; i <= middle; i++) {
977 filter[i] = filter[i] / sum;
978 }
979 }
980 }
981
996 template <typename FilterType>
997 static void getGaussianDerivativeKernel(FilterType *filter, unsigned int size, FilterType sigma = 0., bool normalize = true)
998 {
999 if (size % 2 != 1)
1000 throw(vpImageException(vpImageException::incorrectInitializationError, "Bad Gaussian filter size"));
1001
1002 if (sigma <= 0)
1003 sigma = static_cast<FilterType>((size - 1) / 6.0);
1004
1005 int middle = (int)(size - 1) / 2;
1006 FilterType sigma2 = static_cast<FilterType>(vpMath::sqr(sigma));
1007 FilterType coef_1 = static_cast<FilterType>(1. / (sigma * sqrt(2. * M_PI)));
1008 FilterType coef_1_over_2 = coef_1 / static_cast<FilterType>(2.);
1009 FilterType _2_coef_1 = static_cast<FilterType>(2.) * coef_1;
1010 FilterType _2_sigma2 = static_cast<FilterType>(2. * sigma2);
1011 filter[0] = 0.;
1012 for (int i = 1; i <= middle; i++) {
1013 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)));
1014 }
1015
1016 if (normalize) {
1017 FilterType sum = 0;
1018 for (int i = 1; i <= middle; i++) {
1019 sum += _2_coef_1 * static_cast<FilterType>(exp(-(i * i) / _2_sigma2));
1020 }
1021 sum += coef_1;
1022
1023 for (int i = 1; i <= middle; i++) {
1024 filter[i] = filter[i] / sum;
1025 }
1026 }
1027 }
1028
1029 // Gradient along X
1030 template<typename FilterType>
1032 {
1033 dIx.resize(I.getHeight(), I.getWidth());
1034 // dIx=0;
1035 for (unsigned int i = 0; i < I.getHeight(); i++) {
1036 for (unsigned int j = 0; j < 3; j++) {
1037 dIx[i][j] = 0;
1038 }
1039 for (unsigned int j = 3; j < I.getWidth() - 3; j++) {
1040 dIx[i][j] = vpImageFilter::derivativeFilterX(I, i, j);
1041 }
1042 for (unsigned int j = I.getWidth() - 3; j < I.getWidth(); j++) {
1043 dIx[i][j] = 0;
1044 }
1045 }
1046 }
1047
1048 template <typename ImageType, typename FilterType>
1049 static void getGradX(const vpImage<ImageType> &I, vpImage<FilterType> &dIx, const FilterType *filter, unsigned int size)
1050 {
1051 dIx.resize(I.getHeight(), I.getWidth());
1052 for (unsigned int i = 0; i < I.getHeight(); i++) {
1053 for (unsigned int j = 0; j < (size - 1) / 2; j++) {
1054 dIx[i][j] = 0;
1055 }
1056 for (unsigned int j = (size - 1) / 2; j < I.getWidth() - (size - 1) / 2; j++) {
1057 dIx[i][j] = vpImageFilter::derivativeFilterX<ImageType, FilterType>(I, i, j, filter, size);
1058 }
1059 for (unsigned int j = I.getWidth() - (size - 1) / 2; j < I.getWidth(); j++) {
1060 dIx[i][j] = 0;
1061 }
1062 }
1063 }
1064
1075 template <typename ImageType, typename FilterType>
1076 static void getGradXGauss2D(const vpImage<ImageType> &I, vpImage<FilterType> &dIx, const FilterType *gaussianKernel,
1077 const FilterType *gaussianDerivativeKernel, unsigned int size)
1078 {
1080 vpImageFilter::filterY<FilterType>(I, GIy, gaussianKernel, size);
1081 vpImageFilter::getGradX<FilterType, FilterType>(GIy, dIx, gaussianDerivativeKernel, size);
1082 }
1083
1084 // Gradient along Y
1085 template <typename FilterType>
1087 {
1088 dIy.resize(I.getHeight(), I.getWidth());
1089 for (unsigned int i = 0; i < 3; i++) {
1090 for (unsigned int j = 0; j < I.getWidth(); j++) {
1091 dIy[i][j] = 0;
1092 }
1093 }
1094 for (unsigned int i = 3; i < I.getHeight() - 3; i++) {
1095 for (unsigned int j = 0; j < I.getWidth(); j++) {
1096 dIy[i][j] = vpImageFilter::derivativeFilterY(I, i, j);
1097 }
1098 }
1099 for (unsigned int i = I.getHeight() - 3; i < I.getHeight(); i++) {
1100 for (unsigned int j = 0; j < I.getWidth(); j++) {
1101 dIy[i][j] = 0;
1102 }
1103 }
1104 }
1105
1106 template <typename ImageType, typename FilterType>
1107 static void getGradY(const vpImage<ImageType> &I, vpImage<FilterType> &dIy, const FilterType *filter, unsigned int size)
1108 {
1109 dIy.resize(I.getHeight(), I.getWidth());
1110 for (unsigned int i = 0; i < (size - 1) / 2; i++) {
1111 for (unsigned int j = 0; j < I.getWidth(); j++) {
1112 dIy[i][j] = 0;
1113 }
1114 }
1115 for (unsigned int i = (size - 1) / 2; i < I.getHeight() - (size - 1) / 2; i++) {
1116 for (unsigned int j = 0; j < I.getWidth(); j++) {
1117 dIy[i][j] = vpImageFilter::derivativeFilterY<ImageType, FilterType>(I, i, j, filter, size);
1118 }
1119 }
1120 for (unsigned int i = I.getHeight() - (size - 1) / 2; i < I.getHeight(); i++) {
1121 for (unsigned int j = 0; j < I.getWidth(); j++) {
1122 dIy[i][j] = 0;
1123 }
1124 }
1125 }
1126
1137 template <typename ImageType, typename FilterType>
1138 static void getGradYGauss2D(const vpImage<ImageType> &I, vpImage<FilterType> &dIy, const FilterType *gaussianKernel,
1139 const FilterType *gaussianDerivativeKernel, unsigned int size)
1140 {
1142 vpImageFilter::filterX<FilterType>(I, GIx, gaussianKernel, size);
1143 vpImageFilter::getGradY<FilterType, FilterType>(GIx, dIy, gaussianDerivativeKernel, size);
1144 }
1145
1153 template <typename FilterType>
1154 inline static FilterType getSobelKernelX(FilterType *filter, unsigned int size)
1155 {
1156 if (size == 0)
1157 throw vpException(vpException::dimensionError, "Cannot get Sobel kernel of size 0!");
1158 if (size > 20)
1159 throw vpException(vpException::dimensionError, "Cannot get Sobel kernel of size > 20!");
1160
1161 vpArray2D<FilterType> SobelY(size * 2 + 1, size * 2 + 1);
1162 FilterType norm = getSobelKernelY<FilterType>(SobelY.data, size);
1163 memcpy(filter, SobelY.t().data, SobelY.getRows() * SobelY.getCols() * sizeof(FilterType));
1164 return norm;
1165 }
1166
1174 template <typename FilterType>
1175 inline static FilterType getSobelKernelY(FilterType *filter, unsigned int size)
1176 {
1177 // Sobel kernel pre-computed for the usual size
1178 static const FilterType SobelY3x3[9] = { -1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0 };
1179 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,
1180 0.0, 0.0, 2.0, 8.0, 12.0, 8.0, 2.0, 1.0, 4.0, 6.0, 4.0, 1.0 };
1181 static const FilterType SobelY7x7[49] = { -1, -6, -15, -20, -15, -6, -1, -4, -24, -60, -80, -60, -24, -4, -5, -30, -75,
1182 -100, -75, -30, -5, 0, 0, 0, 0, 0, 0, 0, 5, 30, 75, 100, 75, 30,
1183 5, 4, 24, 60, 80, 60, 24, 4, 1, 6, 15, 20, 15, 6, 1 };
1184 const vpArray2D<FilterType> smoothingKernel(3, 3);
1185 smoothingKernel[0][0] = 1.0;
1186 smoothingKernel[0][1] = 2.0;
1187 smoothingKernel[0][2] = 1.0;
1188 smoothingKernel[1][0] = 2.0;
1189 smoothingKernel[1][1] = 4.0;
1190 smoothingKernel[1][2] = 2.0;
1191 smoothingKernel[2][0] = 1.0;
1192 smoothingKernel[2][1] = 2.0;
1193 smoothingKernel[2][2] = 1.0;
1194
1195 if (size == 0)
1196 throw vpException(vpException::dimensionError, "Cannot get Sobel kernel of size 0!");
1197 if (size > 20)
1198 throw vpException(vpException::dimensionError, "Cannot get Sobel kernel of size > 20!");
1199
1200 const unsigned int kernel_size = size * 2 + 1;
1201 if (kernel_size == 3) {
1202 memcpy(filter, SobelY3x3, kernel_size * kernel_size * sizeof(FilterType));
1203 return 1 / 8.0;
1204 }
1205 if (kernel_size == 5) {
1206 memcpy(filter, SobelY5x5, kernel_size * kernel_size * sizeof(FilterType));
1207 return 1 / 16.0;
1208 }
1209 if (kernel_size == 7) {
1210 memcpy(filter, SobelY7x7, kernel_size * kernel_size * sizeof(FilterType));
1211 return 1 / 16.0;
1212 }
1213
1214 vpArray2D<FilterType> sobelY(7, 7);
1215 memcpy(sobelY.data, SobelY7x7, sobelY.getRows() * sobelY.getCols() * sizeof(FilterType));
1216 for (unsigned int i = 4; i <= size; i++) {
1217 sobelY = vpArray2D<FilterType>::conv2(sobelY, smoothingKernel, "full");
1218 }
1219
1220 memcpy(filter, sobelY.data, sobelY.getRows() * sobelY.getCols() * sizeof(FilterType));
1221
1222 return 1 / 16.0;
1223 }
1224
1225#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
1226 static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh);
1227 static float computeCannyThreshold(const vpImage<unsigned char> &I, float &lowerThresh);
1228 static float median(const cv::Mat &cv_I);
1229 static float median(const vpImage<unsigned char> &Isrc);
1230 static std::vector<float> median(const vpImage<vpRGBa> &Isrc);
1231#endif
1232};
1233
1234#endif
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition vpArray2D.h:131
unsigned int getCols() const
Definition vpArray2D.h:280
Type * data
Address of the first element of the data array.
Definition vpArray2D.h:144
static vpArray2D< Type > conv2(const vpArray2D< Type > &M, const vpArray2D< Type > &kernel, const std::string &mode)
Definition vpArray2D.h:1070
vpArray2D< Type > t() const
Compute the transpose of the array.
Definition vpArray2D.h:1059
unsigned int getRows() const
Definition vpArray2D.h:290
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ dimensionError
Bad dimension.
Definition vpException.h:83
Error that can be emitted by the vpImage class and its derivatives.
@ incorrectInitializationError
Wrong image initialization.
Various image filter, convolution, etc...
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static double filterXG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double derivativeFilterY(const vpImage< T > &I, unsigned int r, unsigned int c)
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 FilterType filterXLeftBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static void gaussianBlur(const vpImage< FilterType > &I, vpImage< FilterType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true)
static void filterX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size)
static void getGradYGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size)
static FilterType getSobelKernelX(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 filterYR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static FilterType filterY(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static void filter(const vpImage< FilterType > &I, vpImage< FilterType > &Iu, vpImage< FilterType > &Iv, const vpArray2D< FilterType > &M, bool convolve=false)
static void getGradXGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size)
static FilterType filterX(const vpImage< FilterType > &I, unsigned int r, unsigned int c, const FilterType *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 gaussianBlur(const vpImage< unsigned char > &I, vpImage< FilterType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true)
static double filterXB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterXR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static FilterType filterX(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static void getGaussianDerivativeKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static double derivativeFilterX(const vpImage< T > &I, unsigned int r, unsigned int c)
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 getGradX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx)
static FilterType filterXRightBorder(const vpImage< FilterType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static FilterType derivativeFilterX(const vpImage< T > &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 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 getGradX(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size)
static void filterYG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static FilterType filterXLeftBorder(const vpImage< FilterType > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterXRightBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterY(const vpImage< FilterType > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size)
static FilterType getSobelKernelY(FilterType *filter, unsigned int size)
static void getGradY(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size)
static FilterType filterY(const vpImage< double > &I, unsigned int r, unsigned int c, const FilterType *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 FilterType derivativeFilterY(const vpImage< T > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static void filterX(const vpImage< FilterType > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size)
static void filterXG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static FilterType filterXRightBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterYG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static FilterType filterYTopBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static FilterType filterYTopBorder(const vpImage< double > &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 double filterYB(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 FilterType filterYBottomBorder(const vpImage< double > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double gaussianFilter(const vpImage< T > &fr, unsigned int r, unsigned int c)
static void filter(const vpImage< unsigned char > &I, vpImage< FilterType > &GI, const FilterType *filter, unsigned int size)
static void filter(const vpImage< FilterType > &I, vpImage< FilterType > &GI, const FilterType *filter, unsigned int size)
static void getGradY(const vpImage< unsigned char > &I, vpImage< FilterType > &dIy)
Definition of the vpImage class member functions.
Definition vpImage.h:135
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
static double sqr(double x)
Definition vpMath.h:124