Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageFilter.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 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#include <visp3/core/vpImageFilter.h>
35#include <visp3/core/vpIoTools.h>
36#include <visp3/core/vpRGBa.h>
37
39
43template
45 const vpArray2D<float> &M, bool convolve, const vpImage<bool> *p_mask);
46
47template
49 const vpArray2D<double> &M, bool convolve, const vpImage<bool> *p_mask);
50
51template
53 const vpArray2D<float> &M, bool convolve, const vpImage<bool> *p_mask);
54
55template
57 const vpArray2D<double> &M, bool convolve, const vpImage<bool> *p_mask);
58
59template
61 unsigned int size, const vpImage<bool> *p_mask);
62
63template
65 unsigned int size, const vpImage<bool> *p_mask);
66
67template
68void vpImageFilter::filter<float, float>(const vpImage<float> &I, vpImage<float> &GI, const float *filter,
69 unsigned int size, const vpImage<bool> *p_mask);
70
71template
72void vpImageFilter::filter<double, double>(const vpImage<double> &I, vpImage<double> &GI, const double *filter,
73 unsigned int size, const vpImage<bool> *p_mask);
77
130 const vpColVector &kernelV)
131{
132 const unsigned int size = kernelH.size(), sizeV = kernelV.size();
133 const unsigned int widthI = I.getWidth(), heightI = I.getHeight();
134 const unsigned int half_size = size / 2;
135
136 If.resize(heightI, widthI, 0.0);
137 vpImage<double> I_filter(heightI, widthI, 0.0);
138
139 for (unsigned int i = 0; i < heightI; ++i) {
140 for (unsigned int j = half_size; j < (widthI - half_size); ++j) {
141 double conv = 0.0;
142 for (unsigned int a = 0; a < size; ++a) {
143 conv += kernelH[a] * static_cast<double>(I[i][(j + half_size) - a]);
144 }
145
146 I_filter[i][j] = conv;
147 }
148 }
149
150 for (unsigned int i = half_size; i < (heightI - half_size); ++i) {
151 for (unsigned int j = 0; j < widthI; ++j) {
152 double conv = 0.0;
153 for (unsigned int a = 0; a < sizeV; ++a) {
154 conv += kernelV[a] * I_filter[(i + half_size) - a][j];
155 }
156
157 If[i][j] = conv;
158 }
159 }
160}
161
165template
167 unsigned int size, const vpImage<bool> *p_mask);
168
169template
171 unsigned int size, const vpImage<bool> *p_mask);
172
173template
174void vpImageFilter::filterX<float, float>(const vpImage<float> &I, vpImage<float> &dIx, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
175
176template
177void vpImageFilter::filterX<double, double>(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
181
182#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
183void vpImageFilter::filterX(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIx, const double *filter, unsigned int size,
184 const vpImage<bool> *p_mask)
185{
186 const unsigned int heightI = I.getHeight(), widthI = I.getWidth();
187 const unsigned int stop1J = (size - 1) / 2;
188 const unsigned int stop2J = widthI - ((size - 1) / 2);
189 resizeAndInitializeIfNeeded(p_mask, heightI, widthI, dIx);
190
191 for (unsigned int i = 0; i < heightI; ++i) {
192 for (unsigned int j = 0; j < stop1J; ++j) {
193 // We have to compute the value for each pixel if we don't have a mask or for
194 // pixels for which the mask is true otherwise
195 bool computeVal = checkBooleanMask(p_mask, i, j);
196 if (computeVal) {
197 dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderR(I, i, j, filter, size));
198 dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderG(I, i, j, filter, size));
199 dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXLeftBorderB(I, i, j, filter, size));
200 }
201 }
202 for (unsigned int j = stop1J; j < stop2J; ++j) {
203 // We have to compute the value for each pixel if we don't have a mask or for
204 // pixels for which the mask is true otherwise
205 bool computeVal = checkBooleanMask(p_mask, i, j);
206 if (computeVal) {
207 dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXR(I, i, j, filter, size));
208 dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXG(I, i, j, filter, size));
209 dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXB(I, i, j, filter, size));
210 }
211 }
212 for (unsigned int j = stop2J; j < widthI; ++j) {
213 // We have to compute the value for each pixel if we don't have a mask or for
214 // pixels for which the mask is true otherwise
215 bool computeVal = checkBooleanMask(p_mask, i, j);
216 if (computeVal) {
217 dIx[i][j].R = static_cast<unsigned char>(vpImageFilter::filterXRightBorderR(I, i, j, filter, size));
218 dIx[i][j].G = static_cast<unsigned char>(vpImageFilter::filterXRightBorderG(I, i, j, filter, size));
219 dIx[i][j].B = static_cast<unsigned char>(vpImageFilter::filterXRightBorderB(I, i, j, filter, size));
220 }
221 }
222 }
223}
224#endif
225
229template
231 unsigned int size, const vpImage<bool> *p_mask);
232
233template
235 unsigned int size, const vpImage<bool> *p_mask);
236
237template
238void vpImageFilter::filterY<float, float>(const vpImage<float> &I, vpImage<float> &dIy, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
239
240template
241void vpImageFilter::filterY<double, double>(const vpImage<double> &I, vpImage<double> &dIy, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
245
246#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
247void vpImageFilter::filterY(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &dIy, const double *filter, unsigned int size,
248 const vpImage<bool> *p_mask)
249{
250 const unsigned int heightI = I.getHeight(), widthI = I.getWidth();
251 const unsigned int stop1I = (size - 1) / 2;
252 const unsigned int stop2I = heightI - ((size - 1) / 2);
253 resizeAndInitializeIfNeeded(p_mask, heightI, widthI, dIy);
254
255 for (unsigned int i = 0; i < stop1I; ++i) {
256 for (unsigned int j = 0; j < widthI; ++j) {
257 // We have to compute the value for each pixel if we don't have a mask or for
258 // pixels for which the mask is true otherwise
259 bool computeVal = checkBooleanMask(p_mask, i, j);
260 if (computeVal) {
261 dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYTopBorderR(I, i, j, filter, size));
262 dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYTopBorderG(I, i, j, filter, size));
263 dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYTopBorderB(I, i, j, filter, size));
264 }
265 }
266 }
267 for (unsigned int i = stop1I; i < stop2I; ++i) {
268 for (unsigned int j = 0; j < widthI; ++j) {
269 // We have to compute the value for each pixel if we don't have a mask or for
270 // pixels for which the mask is true otherwise
271 bool computeVal = checkBooleanMask(p_mask, i, j);
272 if (computeVal) {
273 dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYR(I, i, j, filter, size));
274 dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYG(I, i, j, filter, size));
275 dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYB(I, i, j, filter, size));
276 }
277 }
278 }
279 for (unsigned int i = stop2I; i < heightI; ++i) {
280 for (unsigned int j = 0; j < widthI; ++j) {
281 // We have to compute the value for each pixel if we don't have a mask or for
282 // pixels for which the mask is true otherwise
283 bool computeVal = checkBooleanMask(p_mask, i, j);
284 if (computeVal) {
285 dIy[i][j].R = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderR(I, i, j, filter, size));
286 dIy[i][j].G = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderG(I, i, j, filter, size));
287 dIy[i][j].B = static_cast<unsigned char>(vpImageFilter::filterYBottomBorderB(I, i, j, filter, size));
288 }
289 }
290 }
291}
292#endif
293
297template
298void vpImageFilter::gaussianBlur<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &GI, unsigned int size, float sigma, bool normalize, const vpImage<bool> *p_mask);
299
300template
301void vpImageFilter::gaussianBlur<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &GI, unsigned int size, double sigma, bool normalize, const vpImage<bool> *p_mask);
302
303template
304void vpImageFilter::gaussianBlur<float, float>(const vpImage<float> &I, vpImage<float> &GI, unsigned int size, float sigma, bool normalize, const vpImage<bool> *p_mask);
305
306template
307void vpImageFilter::gaussianBlur<double, double>(const vpImage<double> &I, vpImage<double> &GI, unsigned int size, double sigma, bool normalize, const vpImage<bool> *p_mask);
311
312#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
325void vpImageFilter::gaussianBlur(const vpImage<vpRGBa> &I, vpImage<vpRGBa> &GI, unsigned int size, double sigma, bool normalize,
326 const vpImage<bool> *p_mask)
327{
328 if (size == 0 || size-1 > I.getWidth() || size-1 > I.getHeight()) {
329 std::ostringstream oss;
330 oss << "Image size (" << I.getWidth() << "x" << I.getHeight() << ") is too small for the Gaussian kernel ("
331 << "size=" << size << "), min size is " << (size-1);
332 throw vpException(vpException::dimensionError, oss.str());
333 }
334
335 double *fg = new double[(size + 1) / 2];
336 vpImageFilter::getGaussianKernel(fg, size, sigma, normalize);
337 vpImage<vpRGBa> GIx;
338 vpImageFilter::filterX(I, GIx, fg, size, p_mask);
339 vpImageFilter::filterY(GIx, GI, fg, size, p_mask);
340 GIx.destroy();
341 delete[] fg;
342}
343#endif
344
348template
349void vpImageFilter::getGaussianKernel<float>(float *filter, unsigned int size, float sigma, bool normalize);
350
351template
352void vpImageFilter::getGaussianDerivativeKernel<float>(float *filter, unsigned int size, float sigma, bool normalize);
353
354template
355void vpImageFilter::getGaussianDerivativeKernel<double>(double *filter, unsigned int size, double sigma, bool normalize);
356
357template
359
360template
362
363template
365
366template
368
369template
370void vpImageFilter::getGradX<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIx, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
371
372template
373void vpImageFilter::getGradX<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
374
375template
376void vpImageFilter::getGradX<float, float>(const vpImage<float> &I, vpImage<float> &dIx, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
377
378template
379void vpImageFilter::getGradX<double, double>(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
380
381template
382void vpImageFilter::getGradY<unsigned char, float>(const vpImage<unsigned char> &I, vpImage<float> &dIy, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
383
384template
385void vpImageFilter::getGradY<unsigned char, double>(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
386
387template
388void vpImageFilter::getGradY<float, float>(const vpImage<float> &I, vpImage<float> &dIy, const float *filter, unsigned int size, const vpImage<bool> *p_mask);
389
390template
391void vpImageFilter::getGradY<double, double>(const vpImage<double> &I, vpImage<double> &dIy, const double *filter, unsigned int size, const vpImage<bool> *p_mask);
392
393template
395 const float *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
396
397template
399 const double *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
400
401template
402void vpImageFilter::getGradXGauss2D<float, float>(const vpImage<float> &I, vpImage<float> &dIx, const float *gaussianKernel,
403 const float *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
404
405template
406void vpImageFilter::getGradXGauss2D<double, double>(const vpImage<double> &I, vpImage<double> &dIx, const double *gaussianKernel,
407 const double *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
408
409template
411 const float *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
412
413template
415 const double *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
416
417template
418void vpImageFilter::getGradYGauss2D<float, float>(const vpImage<float> &I, vpImage<float> &dIy, const float *gaussianKernel,
419 const float *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
420
421template
422void vpImageFilter::getGradYGauss2D<double, double>(const vpImage<double> &I, vpImage<double> &dIy, const double *gaussianKernel,
423 const double *gaussianDerivativeKernel, unsigned int size, const vpImage<bool> *p_mask);
427
428 // Operation for Gaussian pyramid
430{
432#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
433#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
434 cv::Mat imgsrc, imgdest;
435 vpImageConvert::convert(I, imgsrc);
436 cv::pyrDown(imgsrc, imgdest, cv::Size(static_cast<int>(I.getWidth()) / 2, static_cast<int>(I.getHeight()) / 2));
437 vpImageConvert::convert(imgdest, GI);
438#else
439 cv::Mat imgsrc, imgdest;
440 vpImageConvert::convert(I, imgsrc);
441 cv::pyrDown(imgsrc, imgdest, cvSize(static_cast<int>(I.getWidth()) / 2, static_cast<int>(I.getHeight()) / 2));
442 vpImageConvert::convert(imgdest, GI);
443#endif
444#else
447#endif
448}
449
451{
452 const unsigned int w = I.getWidth() / 2;
453 const unsigned int height = I.getHeight();
454 const unsigned int val_2 = 2;
455
456 GI.resize(height, w);
457 for (unsigned int i = 0; i < height; ++i) {
458 GI[i][0] = I[i][0];
459 for (unsigned int j = 1; j < (w - 1); ++j) {
460 GI[i][j] = vpImageFilter::filterGaussXPyramidal(I, i, val_2 * j);
461 }
462 GI[i][w - 1] = I[i][(val_2 * w) - 1];
463 }
464}
465
467{
468 const unsigned int h = I.getHeight() / 2;
469 const unsigned int width = I.getWidth();
470 const unsigned int val_2 = 2;
471
472 GI.resize(h, width);
473 for (unsigned int j = 0; j < width; ++j) {
474 GI[0][j] = I[0][j];
475 for (unsigned int i = 1; i < (h - 1); ++i) {
476 GI[i][j] = vpImageFilter::filterGaussYPyramidal(I, val_2 * i, j);
477 }
478 GI[h - 1][j] = I[(val_2 * h) - 1][j];
479 }
480}
481
485template
486double vpImageFilter::getSobelKernelX<double>(double *filter, unsigned int size);
487
488template
489float vpImageFilter::getSobelKernelX<float>(float *filter, unsigned int size);
490
491template
492double vpImageFilter::getSobelKernelY<double>(double *filter, unsigned int size);
493
494template
495float vpImageFilter::getSobelKernelY<float>(float *filter, unsigned int size);
499
500
501#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
507float vpImageFilter::median(const cv::Mat &channel)
508{
509 float m = (channel.rows * channel.cols) / 2.f;
510 int bin = 0;
511 float med = -1.0f;
512
513 int histSize = 256;
514 float range[] = { 0, 256 };
515 const float *histRange = { range };
516 bool uniform = true;
517 bool accumulate = false;
518 cv::Mat hist;
519 cv::calcHist(&channel, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
520
521 int i = 0;
522 while ((i < histSize) && (med < 0.0f)) {
523 bin += cvRound(hist.at<float>(i));
524 if ((bin > m) && (med < 0.0f)) {
525 med = static_cast<float>(i);
526 }
527 ++i;
528 }
529
530 return med;
531}
532
541{
542 cv::Mat cv_I;
543 vpImageConvert::convert(Isrc, cv_I);
544 return median(cv_I);
545}
546
555std::vector<float> vpImageFilter::median(const vpImage<vpRGBa> &Isrc)
556{
557 cv::Mat cv_I_bgr;
558 vpImageConvert::convert(Isrc, cv_I_bgr);
559 std::vector<cv::Mat> channels;
560 cv::split(cv_I_bgr, channels);
561 std::vector<float> meds(3);
562 const int orderMeds[] = { 2, 1, 0 }; // To keep the order R, G, B
563 const int orderCvChannels[] = { 0, 1, 2 }; // Because the order of the cv::Mat is B, G, R
564 const unsigned int val_3 = 3;
565 for (unsigned int i = 0; i < val_3; ++i) {
566 meds[orderMeds[i]] = median(channels[orderCvChannels[i]]);
567 }
568 return meds;
569}
570
571
589 cv::Mat &cv_dIx, cv::Mat &cv_dIy,
590 const bool &computeDx, const bool &computeDy, const bool &normalize,
591 const unsigned int &gaussianKernelSize, const float &gaussianStdev,
592 const unsigned int &apertureGradient,
594{
596 || (filteringType == vpImageFilter::CANNY_GBLUR_SOBEL_FILTERING)) {
597 cv::Mat img_blur;
598 // Apply Gaussian blur to the image
599 cv::Size gsz(gaussianKernelSize, gaussianKernelSize);
600 cv::GaussianBlur(cv_I, img_blur, gsz, gaussianStdev);
601
602 // Compute the gradient of the blurred image
603 if (filteringType == vpImageFilter::CANNY_GBLUR_SOBEL_FILTERING) {
604 double scale = 1.;
605 if (normalize) {
606 scale = 1. / 8.;
607 if (apertureGradient > 3) {
608 scale *= std::pow(1. / 2., (static_cast<double>(apertureGradient) * 2. - 3.)); // 1 / 2^(2 x ksize - dx - dy -2) with ksize =apertureGradient and dx xor dy = 1
609 }
610 }
611 if (computeDx) {
612 cv::Sobel(img_blur, cv_dIx, CV_16S, 1, 0, apertureGradient, scale, 0., cv::BORDER_REPLICATE);
613 }
614 if (computeDy) {
615 cv::Sobel(img_blur, cv_dIy, CV_16S, 0, 1, apertureGradient, scale, 0., cv::BORDER_REPLICATE);
616 }
617 }
618 else if (filteringType == vpImageFilter::CANNY_GBLUR_SCHARR_FILTERING) {
619 double scale = 1.;
620 if (normalize) {
621 scale = 1. / 32.;
622 }
623 if (computeDx) {
624 cv::Scharr(img_blur, cv_dIx, CV_16S, 1, 0, scale);
625 }
626 if (computeDy) {
627 cv::Scharr(img_blur, cv_dIy, CV_16S, 0, 1, scale);
628 }
629 }
630 }
631}
632#endif
633
637template
640 const bool &computeDx, const bool &computeDy, const bool &normalize,
641 const unsigned int &gaussianKernelSize, const float &gaussianStdev,
642 const unsigned int &apertureGradient,
643 const vpCannyFilteringAndGradientType &filteringType,
644 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
645
646template
649 const bool &computeDx, const bool &computeDy, const bool &normalize,
650 const unsigned int &gaussianKernelSize, const double &gaussianStdev,
651 const unsigned int &apertureGradient,
652 const vpCannyFilteringAndGradientType &filteringType,
653 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
654
655template
658 const bool &computeDx, const bool &computeDy, const bool &normalize,
659 const unsigned int &gaussianKernelSize, const float &gaussianStdev,
660 const unsigned int &apertureGradient,
661 const vpCannyFilteringAndGradientType &filteringType,
662 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
663
664template
667 const bool &computeDx, const bool &computeDy, const bool &normalize,
668 const unsigned int &gaussianKernelSize, const double &gaussianStdev,
669 const unsigned int &apertureGradient,
670 const vpCannyFilteringAndGradientType &filteringType,
671 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
672
673template
676 const bool &computeDx, const bool &computeDy, const bool &normalize,
677 const unsigned int &gaussianKernelSize, const float &gaussianStdev,
678 const unsigned int &apertureGradient,
679 const vpCannyFilteringAndGradientType &filteringType,
680 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
681
682template
685 const bool &computeDx, const bool &computeDy, const bool &normalize,
686 const unsigned int &gaussianKernelSize, const double &gaussianStdev,
687 const unsigned int &apertureGradient,
688 const vpCannyFilteringAndGradientType &filteringType,
689 const vpCannyBackendType &backend, const vpImage<bool> *p_mask);
690
691template
693 const vpImage<double> *p_dIx, const vpImage<double> *p_dIy,
694 const unsigned int &gaussianKernelSize,
695 const double &gaussianStdev, const unsigned int &apertureGradient,
696 const float &lowerThresholdRatio, const float &upperThresholdRatio,
698 const vpImage<bool> *p_mask);
699
700template
702 const vpImage<float> *p_dIx, const vpImage<float> *p_dIy,
703 const unsigned int &gaussianKernelSize,
704 const float &gaussianStdev, const unsigned int &apertureGradient,
705 const float &lowerThresholdRatio, const float &upperThresholdRatio,
707 const vpImage<bool> *p_mask);
711
712END_VISP_NAMESPACE
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition vpArray2D.h:146
unsigned int size() const
Return the number of elements of the 2D array.
Definition vpArray2D.h:435
Implementation of column vector and the associated operations.
@ dimensionError
Bad dimension.
Definition vpException.h:71
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void filterY(const vpImage< ImageType > &I, vpImage< OutputType > &dIy, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
Filter along the vertical direction.
static void getGradX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx, const vpImage< bool > *p_mask=nullptr)
static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_dIx, const cv::Mat *p_cv_dIy, float &lowerThresh, const unsigned int &gaussianKernelSize=5, const float &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const float &lowerThresholdRatio=0.6f, const float &upperThresholdRatio=0.8f, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING)
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 filterX(const vpImage< ImageType > &I, vpImage< OutputType > &dIx, const FilterType *filter, unsigned int size, const vpImage< bool > *p_mask=nullptr)
Filter along the horizontal direction.
vpCannyFilteringAndGradientType
Canny filter and gradient operators to apply on the image before the edge detection stage.
@ CANNY_GBLUR_SOBEL_FILTERING
Apply Gaussian blur + Sobel operator on the input image.
@ CANNY_GBLUR_SCHARR_FILTERING
Apply Gaussian blur + Scharr operator on the input image.
static void getGaussianDerivativeKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false, const vpImage< bool > *p_mask=nullptr)
static void sepFilter(const vpImage< unsigned char > &I, vpImage< double > &If, const vpColVector &kernelH, const vpColVector &kernelV)
static void gaussianBlur(const vpImage< ImageType > &I, vpImage< OutputType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true, const vpImage< bool > *p_mask=nullptr)
static void getGaussXPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static void getGaussianKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static void getGaussYPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static float median(const cv::Mat &cv_I)
Calculates the median value of a single channel. The algorithm is based on based on https://github....
static FilterType getSobelKernelY(FilterType *filter, unsigned int size)
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 void getGradY(const vpImage< unsigned char > &I, vpImage< FilterType > &dIy, const vpImage< bool > *p_mask=nullptr)
static unsigned char filterGaussYPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void getGaussPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static void computePartialDerivatives(const cv::Mat &cv_I, cv::Mat &cv_dIx, cv::Mat &cv_dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int &gaussianKernelSize=5, const float &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING)
Compute the partial derivatives (i.e. horizontal and vertical gradients) of the input image.
Definition of the vpImage class member functions.
Definition vpImage.h:131
void destroy()
Destructor : Memory de-allocation.
Definition vpImage.h:573
unsigned int getWidth() const
Definition vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition vpImage.h:544
unsigned int getHeight() const
Definition vpImage.h:181