GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-7413740dd8
findzc.c
Go to the documentation of this file.
1 /**
2  * \file findzc.c
3  *
4  * \brief Zero Crossing functions.
5  *
6  * This program 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 (at
9  * your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * \author GRASS GIS Development Team
21  * \author Brad Douglas - rez at touchofmadness com
22  *
23  * \date 2006
24  */
25 
26 #include <stdio.h>
27 #include <math.h>
28 
29 /** \def TINY Defined as 1.0e-3 */
30 #define TINY 1.0e-3
31 
32 /**
33  * \fn int G_math_findzc (double conv[], int size, double zc[], double thresh,
34  * int num_orients)
35  *
36  * \brief Finds locations and orientations of zero crossings.
37  *
38  * Finds the locations and orientations of zero crossings in the input
39  * array <b>conv</b>, which is the result of the convolution of the
40  * Marr-Hildreth operator with the image. The output array is <b>zc</b>,
41  * which is non-zero only at zero crossing pixels. At those pixels, the
42  * value is 1 + (orientation), where orientation is a value from 0 to
43  * <b>num_orients</b>.
44  *
45  * \param[in] conv input
46  * \param[in] size size of largest matrix column or row
47  * \param[out] zc output
48  * \param[in] thresh magnitude threshold
49  * \param[in] num_orients
50  * \return int always returns 0
51  */
52 
53 int G_math_findzc(double conv[], int size, double zc[], double thresh,
54  int num_orients)
55 {
56  int i, j, p;
57 
58  /* go through entire conv image - but skip border rows and cols */
59  for (i = 1; i < size - 1; i++) {
60  for (p = i * size + 1, j = 1; j < size - 1; j++, p++) {
61  int nbr[4];
62  int ni;
63 
64  /* examine the 4-neighbors of position p */
65  nbr[0] = p - 1; /* left */
66  nbr[1] = p + 1; /* right */
67  nbr[2] = p - size; /* up */
68  nbr[3] = p + size; /* down */
69 
70  zc[p] = 0;
71 
72  for (ni = 0; ni < 4; ni++) {
73  /* condition for a zc: sign is different than a neighbor
74  * and the absolute value is less than that neighbor.
75  * Also, threshold magnitudes to eliminate noise
76  */
77  if ((((conv[p] > 0) && (conv[nbr[ni]] < 0)) ||
78  ((conv[p] < 0) && (conv[nbr[ni]] > 0))) &&
79  (fabs(conv[p]) < fabs(conv[nbr[ni]])) &&
80  (fabs(conv[p] - conv[nbr[ni]]) > thresh)) {
81  double ang;
82  int dir;
83 
84  /* found a zc here, get angle of gradient */
85  if (fabs(conv[nbr[1]] - conv[nbr[0]]) < TINY) {
86  ang = M_PI_2;
87 
88  if (conv[nbr[2]] - conv[nbr[3]] < 0)
89  ang = -ang;
90  }
91  else
92  ang = atan2(conv[nbr[2]] - conv[nbr[3]],
93  conv[nbr[1]] - conv[nbr[0]]);
94 
95  /* scale -PI..PI to 0..num_orients - 1 */
96  dir = num_orients * ((ang + M_PI) / (M_PI * 2.0)) + 0.4999;
97 
98  /* shift scale so that 0 (not 8) is straight down */
99  dir = (3 * num_orients / 4 + dir) % num_orients;
100 
101  /* add to differentiate between no zc and an orientation */
102  zc[p] = 1 + dir;
103  break; /* quit looking at neighbors */
104  }
105  } /* for ni */
106  } /* for p */
107  }
108 
109  return 0;
110 }
int G_math_findzc(double conv[], int size, double zc[], double thresh, int num_orients)
Finds locations and orientations of zero crossings.
Definition: findzc.c:53
#define TINY
Definition: findzc.c:30
#define M_PI_2
Definition: gis.h:161
#define M_PI
Definition: gis.h:158