GteImageUtility3.h
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 #pragma once
9 
10 #include <Imagics/GteImage3.h>
11 
12 namespace gte
13 {
14 
16 {
17 public:
18  // All but the Draw* functions are operations on binary images. Let the
19  // image have d0 columns, d1 rows, and d2 slices. The input image must
20  // have zeros on its boundaries x = 0, x = d0-1, y = 0, y = d1-1, z = 0,
21  // and z = d2-1. The 0-valued voxels are considered to be background.
22  // The 1-valued voxels are considered to be foreground. In some of the
23  // operations, to save memory and time the input image is modified by the
24  // algorithms. If you need to preserve the input image, make a copy of it
25  // before calling these functions.
26 
27  // Compute the 6-connected components of a binary image. The input image
28  // is modified to avoid the cost of making a copy. On output, the image
29  // values are the labels for the components. The array components[k],
30  // k >= 1, contains the indices for the k-th component.
31  static void GetComponents6(Image3<int>& image,
32  std::vector<std::vector<size_t>>& components);
33 
34  // Compute the 18-connected components of a binary image. The input image
35  // is modified to avoid the cost of making a copy. On output, the image
36  // values are the labels for the components. The array components[k],
37  // k >= 1, contains the indices for the k-th component.
38  static void GetComponents18(Image3<int>& image,
39  std::vector<std::vector<size_t>>& components);
40 
41  // Compute the 26-connected components of a binary image. The input image
42  // is modified to avoid the cost of making a copy. On output, the image
43  // values are the labels for the components. The array components[k],
44  // k >= 1, contains the indices for the k-th component.
45  static void GetComponents26(Image3<int>& image,
46  std::vector<std::vector<size_t>>& components);
47 
48  // Dilate the image using a structuring element that contains the
49  // 6-connected neighbors.
50  static void Dilate6(Image3<int> const& inImage, Image3<int>& outImage);
51 
52  // Dilate the image using a structuring element that contains the
53  // 18-connected neighbors.
54  static void Dilate18(Image3<int> const& inImage, Image3<int>& outImage);
55 
56  // Dilate the image using a structuring element that contains the
57  // 26-connected neighbors.
58  static void Dilate26(Image3<int> const& inImage, Image3<int>& outImage);
59 
60  // Compute coordinate-directional convex set. For a given coordinate
61  // direction (x, y, or z), identify the first and last 1-valued voxels
62  // on a segment of voxels in that direction. All voxels from first to
63  // last are set to 1. This is done for all segments in each of the
64  // coordinate directions.
65  static void ComputeCDConvex(Image3<int>& image);
66 
67  // Use a depth-first search for filling a 6-connected region. This is
68  // nonrecursive, simulated by using a heap-allocated "stack". The input
69  // (x,y,z) is the seed point that starts the fill.
70  template <typename PixelType>
71  static void FloodFill6(Image3<PixelType>& image, int x, int y, int z,
72  PixelType foreColor, PixelType backColor);
73 
74  // Visit pixels using Bresenham's line drawing algorithm. The callback
75  // represents the action you want applied to each voxel as it is visited.
76  static void DrawLine(int x0, int y0, int z0, int x1, int y1, int z1,
77  std::function<void(int, int, int)> const& callback);
78 
79 private:
80  // Dilation using the specified structuring element.
81  static void Dilate(int numNeighbors, std::array<int, 3> const* delta,
82  Image3<int> const& inImage, Image3<int>& outImage);
83 
84  // Connected component labeling using depth-first search.
85  static void GetComponents(int numNeighbors, int const* delta,
86  Image3<int>& image, std::vector<std::vector<size_t>>& components);
87 };
88 
89 
90 template <typename PixelType>
92  int z, PixelType foreColor, PixelType backColor)
93 {
94  // Test for a valid seed.
95  int const dim0 = image.GetDimension(0);
96  int const dim1 = image.GetDimension(1);
97  int const dim2 = image.GetDimension(2);
98  if (x < 0 || x >= dim0 || y < 0 || y >= dim1 || z < 0 || z >= dim2)
99  {
100  // The seed point is outside the image domain, so nothing to fill.
101  return;
102  }
103 
104  // Allocate the maximum amount of space needed for the stack. An empty
105  // stack has top == -1.
106  size_t const numVoxels = image.GetNumPixels();
107  std::vector<int> xStack(numVoxels), yStack(numVoxels), zStack(numVoxels);
108 
109  // Push seed point onto stack if it has the background color. All points
110  // pushed onto stack have background color backColor.
111  int top = 0;
112  xStack[top] = x;
113  yStack[top] = y;
114  zStack[top] = z;
115 
116  while (top >= 0) // stack is not empty
117  {
118  // Read top of stack. Do not pop since we need to return to this
119  // top value later to restart the fill in a different direction.
120  x = xStack[top];
121  y = yStack[top];
122  z = zStack[top];
123 
124  // Fill the pixel.
125  image(x, y, z) = foreColor;
126 
127  int xp1 = x + 1;
128  if (xp1 < dim0 && image(xp1, y, z) == backColor)
129  {
130  // Push pixel with background color.
131  ++top;
132  xStack[top] = xp1;
133  yStack[top] = y;
134  zStack[top] = z;
135  continue;
136  }
137 
138  int xm1 = x - 1;
139  if (0 <= xm1 && image(xm1, y, z) == backColor)
140  {
141  // Push pixel with background color.
142  ++top;
143  xStack[top] = xm1;
144  yStack[top] = y;
145  zStack[top] = z;
146  continue;
147  }
148 
149  int yp1 = y + 1;
150  if (yp1 < dim1 && image(x, yp1, z) == backColor)
151  {
152  // Push pixel with background color.
153  ++top;
154  xStack[top] = x;
155  yStack[top] = yp1;
156  zStack[top] = z;
157  continue;
158  }
159 
160  int ym1 = y - 1;
161  if (0 <= ym1 && image(x, ym1, z) == backColor)
162  {
163  // Push pixel with background color.
164  ++top;
165  xStack[top] = x;
166  yStack[top] = ym1;
167  zStack[top] = z;
168  continue;
169  }
170 
171  int zp1 = z + 1;
172  if (zp1 < dim2 && image(x, y, zp1) == backColor)
173  {
174  // Push pixel with background color.
175  ++top;
176  xStack[top] = x;
177  yStack[top] = y;
178  zStack[top] = zp1;
179  continue;
180  }
181 
182  int zm1 = z - 1;
183  if (0 <= zm1 && image(x, y, zm1) == backColor)
184  {
185  // Push pixel with background color.
186  ++top;
187  xStack[top] = x;
188  yStack[top] = y;
189  zStack[top] = zm1;
190  continue;
191  }
192 
193  // Done in all directions, pop and return to search other directions.
194  --top;
195  }
196 }
197 
198 }
int GetDimension(int d) const
Definition: GteImage.h:169
GLenum GLenum GLsizei void * image
Definition: glext.h:2724
GLint GLenum GLint x
Definition: glcorearb.h:404
GLfixed y1
Definition: glext.h:4952
size_t GetNumPixels() const
Definition: GteImage.h:193
GLuint GLfloat x0
Definition: glext.h:9013
static void FloodFill6(Image3< PixelType > &image, int x, int y, int z, PixelType foreColor, PixelType backColor)
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:843
GLuint GLfloat GLfloat GLfloat x1
Definition: glext.h:9013
GLenum GLenum GLuint components
Definition: glext.h:8352
GLuint GLfloat GLfloat y0
Definition: glext.h:9013
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:6472
GLint y
Definition: glcorearb.h:98
#define GTE_IMPEXP
Definition: GTEngineDEF.h:63


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