GteImageUtility3.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
10 using namespace gte;
11 
13  std::vector<std::vector<size_t>>& components)
14 {
15  std::array<int, 6> neighbors;
16  image.GetNeighborhood(neighbors);
17  GetComponents(6, &neighbors[0], image, components);
18 }
19 
21  std::vector<std::vector<size_t>>& components)
22 {
23  std::array<int, 18> neighbors;
24  image.GetNeighborhood(neighbors);
25  GetComponents(18, &neighbors[0], image, components);
26 }
27 
29  std::vector<std::vector<size_t>>& components)
30 {
31  std::array<int, 26> neighbors;
32  image.GetNeighborhood(neighbors);
33  GetComponents(26, &neighbors[0], image, components);
34 }
35 
36 void ImageUtility3::Dilate6(Image3<int> const& inImage, Image3<int>& outImage)
37 {
38  std::array<std::array<int, 3>, 6> neighbors;
39  inImage.GetNeighborhood(neighbors);
40  Dilate(6, &neighbors[0], inImage, outImage);
41 }
42 
44  Image3<int>& outImage)
45 {
46  std::array<std::array<int, 3>, 18> neighbors;
47  inImage.GetNeighborhood(neighbors);
48  Dilate(18, &neighbors[0], inImage, outImage);
49 }
50 
52  Image3<int>& outImage)
53 {
54  std::array<std::array<int, 3>, 26> neighbors;
55  inImage.GetNeighborhood(neighbors);
56  Dilate(26, &neighbors[0], inImage, outImage);
57 }
58 
60 {
61  int const dim0 = image.GetDimension(0);
62  int const dim1 = image.GetDimension(1);
63  int const dim2 = image.GetDimension(2);
64 
65  Image3<int> temp = image;
66  int i0, i1, i2;
67  for (i1 = 0; i1 < dim1; ++i1)
68  {
69  for (i0 = 0; i0 < dim0; ++i0)
70  {
71  int i2min;
72  for (i2min = 0; i2min < dim2; ++i2min)
73  {
74  if ((temp(i0, i1, i2min) & 1) == 0)
75  {
76  temp(i0, i1, i2min) |= 2;
77  }
78  else
79  {
80  break;
81  }
82  }
83  if (i2min < dim2)
84  {
85  int i2max;
86  for (i2max = dim2 - 1; i2max >= i2min; --i2max)
87  {
88  if ((temp(i0, i1, i2max) & 1) == 0)
89  {
90  temp(i0, i1, i2max) |= 2;
91  }
92  else
93  {
94  break;
95  }
96  }
97  }
98  }
99  }
100 
101  for (i2 = 0; i2 < dim2; ++i2)
102  {
103  for (i0 = 0; i0 < dim0; ++i0)
104  {
105  int i1min;
106  for (i1min = 0; i1min < dim1; ++i1min)
107  {
108  if ((temp(i0, i1min, i2) & 1) == 0)
109  {
110  temp(i0, i1min, i2) |= 2;
111  }
112  else
113  {
114  break;
115  }
116  }
117  if (i1min < dim1)
118  {
119  int i1max;
120  for (i1max = dim1 - 1; i1max >= i1min; --i1max)
121  {
122  if ((temp(i0, i1max, i2) & 1) == 0)
123  {
124  temp(i0, i1max, i2) |= 2;
125  }
126  else
127  {
128  break;
129  }
130  }
131  }
132  }
133  }
134 
135  for (i2 = 0; i2 < dim2; ++i2)
136  {
137  for (i1 = 0; i1 < dim1; ++i1)
138  {
139  int i0min;
140  for (i0min = 0; i0min < dim0; ++i0min)
141  {
142  if ((temp(i0min, i1, i2) & 1) == 0)
143  {
144  temp(i0min, i1, i2) |= 2;
145  }
146  else
147  {
148  break;
149  }
150  }
151  if (i0min < dim0)
152  {
153  int i0max;
154  for (i0max = dim0 - 1; i0max >= i0min; --i0max)
155  {
156  if ((temp(i0max, i1, i2) & 1) == 0)
157  {
158  temp(i0max, i1, i2) |= 2;
159  }
160  else
161  {
162  break;
163  }
164  }
165  }
166  }
167  }
168 
169  for (size_t i = 0; i < image.GetNumPixels(); ++i)
170  {
171  image[i] = (temp[i] & 2 ? 0 : 1);
172  }
173 }
174 
175 void ImageUtility3::DrawLine(int x0, int y0, int z0, int x1, int y1, int z1,
176  std::function<void(int, int, int)> const& callback)
177 {
178  // Starting point of line.
179  int x = x0, y = y0, z = z0;
180 
181  // Direction of line.
182  int dx = x1-x0, dy = y1-y0, dz = z1-z0;
183 
184  // Increment or decrement depending on direction of line.
185  int sx = (dx > 0 ? 1 : (dx < 0 ? -1 : 0));
186  int sy = (dy > 0 ? 1 : (dy < 0 ? -1 : 0));
187  int sz = (dz > 0 ? 1 : (dz < 0 ? -1 : 0));
188 
189  // Decision parameters for voxel selection.
190  if (dx < 0)
191  {
192  dx = -dx;
193  }
194  if (dy < 0)
195  {
196  dy = -dy;
197  }
198  if (dz < 0)
199  {
200  dz = -dz;
201  }
202  int ax = 2*dx, ay = 2*dy, az = 2*dz;
203  int decX, decY, decZ;
204 
205  // Determine largest direction component, single-step related variable.
206  int maxValue = dx, var = 0;
207  if (dy > maxValue)
208  {
209  maxValue = dy;
210  var = 1;
211  }
212  if (dz > maxValue)
213  {
214  var = 2;
215  }
216 
217  // Traverse Bresenham line.
218  switch (var)
219  {
220  case 0: // Single-step in x-direction.
221  decY = ay - dx;
222  decZ = az - dx;
223  for (; ; x += sx, decY += ay, decZ += az)
224  {
225  // Process voxel.
226  callback(x, y, z);
227 
228  // Take Bresenham step.
229  if (x == x1)
230  {
231  break;
232  }
233  if (decY >= 0)
234  {
235  decY -= ax;
236  y += sy;
237  }
238  if (decZ >= 0)
239  {
240  decZ -= ax;
241  z += sz;
242  }
243  }
244  break;
245  case 1: // Single-step in y-direction.
246  decX = ax - dy;
247  decZ = az - dy;
248  for (; ; y += sy, decX += ax, decZ += az)
249  {
250  // Process voxel.
251  callback(x, y, z);
252 
253  // Take Bresenham step.
254  if (y == y1)
255  {
256  break;
257  }
258  if (decX >= 0)
259  {
260  decX -= ay;
261  x += sx;
262  }
263  if (decZ >= 0)
264  {
265  decZ -= ay;
266  z += sz;
267  }
268  }
269  break;
270  case 2: // Single-step in z-direction.
271  decX = ax - dz;
272  decY = ay - dz;
273  for (; ; z += sz, decX += ax, decY += ay)
274  {
275  // Process voxel.
276  callback(x, y, z);
277 
278  // Take Bresenham step.
279  if (z == z1)
280  {
281  break;
282  }
283  if (decX >= 0)
284  {
285  decX -= az;
286  x += sx;
287  }
288  if (decY >= 0)
289  {
290  decY -= az;
291  y += sy;
292  }
293  }
294  break;
295  }
296 }
297 
298 void ImageUtility3::Dilate(int numNeighbors, std::array<int, 3> const* delta,
299  Image3<int> const& inImage, Image3<int>& outImage)
300 {
301  int const bound0M1 = inImage.GetDimension(0) - 1;
302  int const bound1M1 = inImage.GetDimension(1) - 1;
303  int const bound2M1 = inImage.GetDimension(2) - 1;
304  for (int i2 = 1; i2 < bound2M1; ++i2)
305  {
306  for (int i1 = 1; i1 < bound1M1; ++i1)
307  {
308  for (int i0 = 1; i0 < bound0M1; ++i0)
309  {
310  if (inImage(i0, i1, i2) == 0)
311  {
312  for (int n = 0; n < numNeighbors; ++n)
313  {
314  int d0 = delta[n][0];
315  int d1 = delta[n][1];
316  int d2 = delta[n][2];
317  if (inImage(i0 + d0, i1 + d1, i2 + d2) == 1)
318  {
319  outImage(i0, i1, i2) = 1;
320  break;
321  }
322  }
323  }
324  else
325  {
326  outImage(i0, i1, i2) = 1;
327  }
328  }
329  }
330  }
331 }
332 
333 void ImageUtility3::GetComponents(int numNeighbors, int const* delta,
334  Image3<int>& image, std::vector<std::vector<size_t>>& components)
335 {
336  size_t const numVoxels = image.GetNumPixels();
337  std::vector<int> numElements(numVoxels);
338  std::vector<size_t> vstack(numVoxels);
339  size_t i, numComponents = 0;
340  int label = 2;
341  for (i = 0; i < numVoxels; ++i)
342  {
343  if (image[i] == 1)
344  {
345  int top = -1;
346  vstack[++top] = i;
347 
348  int& count = numElements[numComponents + 1];
349  count = 0;
350  while (top >= 0)
351  {
352  size_t v = vstack[top];
353  image[v] = -1;
354  int j;
355  for (j = 0; j < numNeighbors; ++j)
356  {
357  size_t adj = v + delta[j];
358  if (image[adj] == 1)
359  {
360  vstack[++top] = adj;
361  break;
362  }
363  }
364  if (j == numNeighbors)
365  {
366  image[v] = label;
367  ++count;
368  --top;
369  }
370  }
371 
372  ++numComponents;
373  ++label;
374  }
375  }
376 
377  if (numComponents > 0)
378  {
379  components.resize(numComponents + 1);
380  for (i = 1; i <= numComponents; ++i)
381  {
382  components[i].resize(numElements[i]);
383  numElements[i] = 0;
384  }
385 
386  for (i = 0; i < numVoxels; ++i)
387  {
388  int value = image[i];
389  if (value != 0)
390  {
391  // Labels started at 2 to support the depth-first search,
392  // so they need to be decremented for the correct labels.
393  image[i] = --value;
394  components[value][numElements[value]] = i;
395  ++numElements[value];
396  }
397  }
398  }
399 }
GLdouble n
Definition: glcorearb.h:2003
static void GetComponents6(Image3< int > &image, std::vector< std::vector< size_t >> &components)
static void Dilate6(Image3< int > const &inImage, Image3< int > &outImage)
int GetDimension(int d) const
Definition: GteImage.h:169
GLenum GLenum GLsizei void * image
Definition: glext.h:2724
GLsizei const GLfloat * value
Definition: glcorearb.h:819
GLint GLenum GLint x
Definition: glcorearb.h:404
static void Dilate26(Image3< int > const &inImage, Image3< int > &outImage)
static void GetComponents18(Image3< int > &image, std::vector< std::vector< size_t >> &components)
void GetNeighborhood(std::array< int, 6 > &nbr) const
Definition: GteImage3.h:465
GLfixed y1
Definition: glext.h:4952
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2540
size_t GetNumPixels() const
Definition: GteImage.h:193
GLuint GLfloat x0
Definition: glext.h:9013
GLint GLsizei count
Definition: glcorearb.h:400
static void GetComponents26(Image3< int > &image, std::vector< std::vector< size_t >> &components)
static void Dilate18(Image3< int > const &inImage, Image3< int > &outImage)
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:843
static void GetComponents(int numNeighbors, int const *delta, Image3< int > &image, std::vector< std::vector< size_t >> &components)
GLuint GLfloat GLfloat GLfloat x1
Definition: glext.h:9013
static void ComputeCDConvex(Image3< int > &image)
const GLdouble * v
Definition: glcorearb.h:832
GLenum GLenum GLuint components
Definition: glext.h:8352
GLuint GLfloat GLfloat y0
Definition: glext.h:9013
static void DrawLine(int x0, int y0, int z0, int x1, int y1, int z1, std::function< void(int, int, int)> const &callback)
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:6472
static void Dilate(int numNeighbors, std::array< int, 3 > const *delta, Image3< int > const &inImage, Image3< int > &outImage)
GLint y
Definition: glcorearb.h:98


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00