Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
vpImageFilter.h
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Various image tools, convolution, ...
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
39 #ifndef vpImageFilter_H
40 #define vpImageFilter_H
41 
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 
53 #include <fstream>
54 #include <iostream>
55 #include <math.h>
56 #include <string.h>
57 
66 class VISP_EXPORT vpImageFilter
67 {
68 public:
69 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)
70  static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, const unsigned int gaussianFilterSize,
71  const double thresholdCanny, const unsigned int apertureSobel);
72 #endif
73 
81  template <class T> static double derivativeFilterX(const vpImage<T> &I, const unsigned int r, const unsigned int c)
82  {
83  return (2047.0 * (I[r][c + 1] - I[r][c - 1]) + 913.0 * (I[r][c + 2] - I[r][c - 2]) +
84  112.0 * (I[r][c + 3] - I[r][c - 3])) /
85  8418.0;
86  }
87 
95  template <class T> static double derivativeFilterY(const vpImage<T> &I, const unsigned int r, const unsigned int c)
96  {
97  return (2047.0 * (I[r + 1][c] - I[r - 1][c]) + 913.0 * (I[r + 2][c] - I[r - 2][c]) +
98  112.0 * (I[r + 3][c] - I[r - 3][c])) /
99  8418.0;
100  }
101 
115  template <class T>
116  static double derivativeFilterX(const vpImage<T> &I, const unsigned int r, const unsigned int c, const double *filter,
117  const unsigned int size)
118  {
119  unsigned int i;
120  double result;
121 
122  result = 0;
123 
124  for (i = 1; i <= (size - 1) / 2; i++) {
125  result += filter[i] * (I[r][c + i] - I[r][c - i]);
126  }
127  return result;
128  }
129 
142  template <class T>
143  static double derivativeFilterY(const vpImage<T> &I, const unsigned int r, const unsigned int c, const double *filter,
144  const unsigned int size)
145  {
146  unsigned int i;
147  double result;
148 
149  result = 0;
150 
151  for (i = 1; i <= (size - 1) / 2; i++) {
152  result += filter[i] * (I[r + i][c] - I[r - i][c]);
153  }
154  return result;
155  }
156 
157  static void filter(const vpImage<double> &I, vpImage<double> &Iu, vpImage<double> &Iv, const vpMatrix &M,
158  const bool convolve = false);
159 
160  static void filter(const vpImage<unsigned char> &I, vpImage<double> &If, const vpMatrix &M,
161  const bool convolve = false);
162 
163  static void sepFilter(const vpImage<unsigned char> &I, vpImage<double> &If, const vpColVector &kernelH,
164  const vpColVector &kernelV);
165 
166  static void filter(const vpImage<unsigned char> &I, vpImage<double> &GI, const double *filter, unsigned int size);
167  static void filter(const vpImage<double> &I, vpImage<double> &GI, const double *filter, unsigned int size);
168 
169  static inline unsigned char filterGaussXPyramidal(const vpImage<unsigned char> &I, unsigned int i, unsigned int j)
170  {
171  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]) /
172  16.);
173  }
174  static inline unsigned char filterGaussYPyramidal(const vpImage<unsigned char> &I, unsigned int i, unsigned int j)
175  {
176  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]) /
177  16.);
178  }
179 
180  static void filterX(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
181  static void filterX(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
182 
183  static inline double filterX(const vpImage<unsigned char> &I, unsigned int r, unsigned int c, const double *filter,
184  unsigned int size)
185  {
186  double result;
187 
188  result = 0;
189 
190  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
191  result += filter[i] * (I[r][c + i] + I[r][c - i]);
192  }
193  return result + filter[0] * I[r][c];
194  }
195 
196  static inline double filterXLeftBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
197  const double *filter, unsigned int size)
198  {
199  double result;
200 
201  result = 0;
202 
203  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
204  if (c > i)
205  result += filter[i] * (I[r][c + i] + I[r][c - i]);
206  else
207  result += filter[i] * (I[r][c + i] + I[r][i - c]);
208  }
209  return result + filter[0] * I[r][c];
210  }
211 
212  static inline double filterXRightBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
213  const double *filter, unsigned int size)
214  {
215  double result;
216 
217  result = 0;
218 
219  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
220  if (c + i < I.getWidth())
221  result += filter[i] * (I[r][c + i] + I[r][c - i]);
222  else
223  result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1] + I[r][c - i]);
224  }
225  return result + filter[0] * I[r][c];
226  }
227 
228  static inline double filterX(const vpImage<double> &I, unsigned int r, unsigned int c, const double *filter,
229  unsigned int size)
230  {
231  double result;
232 
233  result = 0;
234 
235  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
236  result += filter[i] * (I[r][c + i] + I[r][c - i]);
237  }
238  return result + filter[0] * I[r][c];
239  }
240 
241  static inline double filterXLeftBorder(const vpImage<double> &I, unsigned int r, unsigned int c, const double *filter,
242  unsigned int size)
243  {
244  double result;
245 
246  result = 0;
247 
248  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
249  if (c > i)
250  result += filter[i] * (I[r][c + i] + I[r][c - i]);
251  else
252  result += filter[i] * (I[r][c + i] + I[r][i - c]);
253  }
254  return result + filter[0] * I[r][c];
255  }
256 
257  static inline double filterXRightBorder(const vpImage<double> &I, unsigned int r, unsigned int c,
258  const double *filter, unsigned int size)
259  {
260  double result;
261 
262  result = 0;
263 
264  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
265  if (c + i < I.getWidth())
266  result += filter[i] * (I[r][c + i] + I[r][c - i]);
267  else
268  result += filter[i] * (I[r][2 * I.getWidth() - c - i - 1] + I[r][c - i]);
269  }
270  return result + filter[0] * I[r][c];
271  }
272 
273  static void filterY(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
274  static void filterY(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
275  static inline double filterY(const vpImage<unsigned char> &I, unsigned int r, unsigned int c, const double *filter,
276  unsigned int size)
277  {
278  double result;
279 
280  result = 0;
281 
282  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
283  result += filter[i] * (I[r + i][c] + I[r - i][c]);
284  }
285  return result + filter[0] * I[r][c];
286  }
287 
288  double static inline filterYTopBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
289  const double *filter, unsigned int size)
290  {
291  double result;
292 
293  result = 0;
294 
295  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
296  if (r > i)
297  result += filter[i] * (I[r + i][c] + I[r - i][c]);
298  else
299  result += filter[i] * (I[r + i][c] + I[i - r][c]);
300  }
301  return result + filter[0] * I[r][c];
302  }
303 
304  double static inline filterYBottomBorder(const vpImage<unsigned char> &I, unsigned int r, unsigned int c,
305  const double *filter, unsigned int size)
306  {
307  double result;
308 
309  result = 0;
310 
311  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
312  if (r + i < I.getHeight())
313  result += filter[i] * (I[r + i][c] + I[r - i][c]);
314  else
315  result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c] + I[r - i][c]);
316  }
317  return result + filter[0] * I[r][c];
318  }
319 
320  static inline double filterYTopBorder(const vpImage<double> &I, unsigned int r, unsigned int c, const double *filter,
321  unsigned int size)
322  {
323  double result;
324 
325  result = 0;
326 
327  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
328  if (r > i)
329  result += filter[i] * (I[r + i][c] + I[r - i][c]);
330  else
331  result += filter[i] * (I[r + i][c] + I[i - r][c]);
332  }
333  return result + filter[0] * I[r][c];
334  }
335 
336  static inline double filterYBottomBorder(const vpImage<double> &I, unsigned int r, unsigned int c,
337  const double *filter, unsigned int size)
338  {
339  double result;
340 
341  result = 0;
342 
343  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
344  if (r + i < I.getHeight())
345  result += filter[i] * (I[r + i][c] + I[r - i][c]);
346  else
347  result += filter[i] * (I[2 * I.getHeight() - r - i - 1][c] + I[r - i][c]);
348  }
349  return result + filter[0] * I[r][c];
350  }
351 
352  static inline double filterY(const vpImage<double> &I, unsigned int r, unsigned int c, const double *filter,
353  unsigned int size)
354  {
355  double result;
356 
357  result = 0;
358 
359  for (unsigned int i = 1; i <= (size - 1) / 2; i++) {
360  result += filter[i] * (I[r + i][c] + I[r - i][c]);
361  }
362  return result + filter[0] * I[r][c];
363  }
364 
365  static void gaussianBlur(const vpImage<unsigned char> &I, vpImage<double> &GI, unsigned int size = 7,
366  double sigma = 0., bool normalize = true);
367  static void gaussianBlur(const vpImage<double> &I, vpImage<double> &GI, unsigned int size = 7, double sigma = 0.,
368  bool normalize = true);
376  template <class T> static double gaussianFilter(const vpImage<T> &fr, const unsigned int r, const unsigned int c)
377  {
378  // filter Gaussien
379  return (15.0 * fr[r][c] + 12.0 * (fr[r - 1][c] + fr[r][c - 1] + fr[r + 1][c] + fr[r][c + 1]) +
380  9.0 * (fr[r - 1][c - 1] + fr[r + 1][c - 1] + fr[r - 1][c + 1] + fr[r + 1][c + 1]) +
381  5.0 * (fr[r - 2][c] + fr[r][c - 2] + fr[r + 2][c] + fr[r][c + 2]) +
382  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] +
383  fr[r + 2][c + 1] + fr[r - 1][c + 2] + fr[r + 1][c + 2]) +
384  2.0 * (fr[r - 2][c - 2] + fr[r + 2][c - 2] + fr[r - 2][c + 2] + fr[r + 2][c + 2])) /
385  159.0;
386  }
387  // operation pour pyramide gaussienne
388  static void getGaussPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
389  static void getGaussXPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
390  static void getGaussYPyramidal(const vpImage<unsigned char> &I, vpImage<unsigned char> &GI);
391 
392  static void getGaussianKernel(double *filter, unsigned int size, double sigma = 0., bool normalize = true);
393  static void getGaussianDerivativeKernel(double *filter, unsigned int size, double sigma = 0., bool normalize = true);
394 
395  // fonction renvoyant le gradient en X de l'image I pour traitement
396  // pyramidal => dimension /2
397  static void getGradX(const vpImage<unsigned char> &I, vpImage<double> &dIx);
398  static void getGradX(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
399  static void getGradX(const vpImage<double> &I, vpImage<double> &dIx, const double *filter, unsigned int size);
400  static void getGradXGauss2D(const vpImage<unsigned char> &I, vpImage<double> &dIx, const double *gaussianKernel,
401  const double *gaussianDerivativeKernel, unsigned int size);
402 
403  // fonction renvoyant le gradient en Y de l'image I
404  static void getGradY(const vpImage<unsigned char> &I, vpImage<double> &dIy);
405  static void getGradY(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *filter, unsigned int size);
406  static void getGradY(const vpImage<double> &I, vpImage<double> &dIy, const double *filter, unsigned int size);
407  static void getGradYGauss2D(const vpImage<unsigned char> &I, vpImage<double> &dIy, const double *gaussianKernel,
408  const double *gaussianDerivativeKernel, unsigned int size);
409 
410  static double getSobelKernelX(double *filter, unsigned int size);
411  static double getSobelKernelY(double *filter, unsigned int size);
412 };
413 
414 #endif
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
static double filterXLeftBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
unsigned int getWidth() const
Definition: vpImage.h:239
static double filterXLeftBorder(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterX(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double derivativeFilterY(const vpImage< T > &I, const unsigned int r, const unsigned int c)
Definition: vpImageFilter.h:95
static unsigned char filterGaussYPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static double gaussianFilter(const vpImage< T > &fr, const unsigned int r, const unsigned int c)
static double filterXRightBorder(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterY(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYBottomBorder(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterX(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYTopBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterXRightBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterY(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYTopBorder(const vpImage< double > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double derivativeFilterY(const vpImage< T > &I, const unsigned int r, const unsigned int c, const double *filter, const unsigned int size)
static double filterYBottomBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
unsigned int getHeight() const
Definition: vpImage.h:178
static double derivativeFilterX(const vpImage< T > &I, const unsigned int r, const unsigned int c)
Definition: vpImageFilter.h:81
static double derivativeFilterX(const vpImage< T > &I, const unsigned int r, const unsigned int c, const double *filter, const unsigned int size)
Various image filter, convolution, etc...
Definition: vpImageFilter.h:66