|
7 | 7 | from stl import mesh |
8 | 8 | from aicscytoparam import cytoparam |
9 | 9 | from aicsimageio import writers |
| 10 | +from skimage import filters as skfilters |
| 11 | +from vtk.util import numpy_support as vtknp |
| 12 | +import pyvista as pv |
| 13 | +import pyacvd |
10 | 14 |
|
11 | 15 | ############################################################################### |
12 | 16 |
|
@@ -134,32 +138,89 @@ def save_mesh_as_stl(polydata, fname): |
134 | 138 |
|
135 | 139 | # Write the mesh to file" |
136 | 140 | nuc_mesh.save(fname) |
137 | | - |
| 141 | + |
| 142 | + |
138 | 143 | def save_mesh_as_obj(polydata, fname): |
139 | | - |
| 144 | + |
140 | 145 | writer = vtk.vtkOBJWriter() |
141 | 146 | writer.SetInputData(polydata) |
142 | 147 | writer.SetFileName(str(fname)) |
143 | 148 | writer.Write() |
144 | 149 |
|
| 150 | + |
145 | 151 | def save_voxelization(polydata, fname): |
146 | | - |
| 152 | + |
147 | 153 | domain, _ = cytoparam.voxelize_meshes([polydata]) |
148 | 154 | with writers.ome_tiff_writer.OmeTiffWriter(fname, overwrite_file=True) as writer: |
149 | 155 | writer.save( |
150 | | - 255*domain, |
| 156 | + 255 * domain, |
151 | 157 | dimension_order='ZYX', |
152 | 158 | image_name=fname.stem |
153 | 159 | ) |
154 | 160 | return domain |
155 | 161 |
|
| 162 | + |
156 | 163 | def save_displacement_map(grid, fname): |
157 | | - |
| 164 | + |
158 | 165 | grid = grid.reshape(1, *grid.shape).astype(np.float32) |
159 | | - |
| 166 | + |
160 | 167 | with writers.ome_tiff_writer.OmeTiffWriter(fname, overwrite_file=True) as writer: |
161 | | - writer.save( |
162 | | - grid, |
163 | | - dimension_order='ZYX', |
164 | | - image_name=fname.stem |
165 | | - ) |
| 168 | + writer.save( |
| 169 | + grid, |
| 170 | + dimension_order='ZYX', |
| 171 | + image_name=fname.stem |
| 172 | + ) |
| 173 | + |
| 174 | + |
| 175 | +def get_smooth_and_coarse_mesh_from_voxelization(img, sigma, npoints): |
| 176 | + """ |
| 177 | + Converts an image into a triangle mesh with even distributed points. |
| 178 | + First we use a Gaussian kernel with size (sigma**3) to smooth the |
| 179 | + input image. Next we apply marching cubes (vtkContourFilter) to obtain |
| 180 | + a first mesh, which is used as input to a Voronoi-based clustering |
| 181 | + that is responsible for remeshing. Details can be found here: |
| 182 | + https://github.com/pyvista/pyacvd |
| 183 | + |
| 184 | + Parameters |
| 185 | + ---------- |
| 186 | + img: np.array |
| 187 | + Input image corresponding to the voxelized version of the original |
| 188 | + average mesh. |
| 189 | + sigma: float |
| 190 | + Gaussian kernel size. |
| 191 | + npoints: int |
| 192 | + Number of points used to create the Voronoi clustering. The larger |
| 193 | + this value the more points the final mesh will have. |
| 194 | + Returns |
| 195 | + ------- |
| 196 | + remesh_vtk: vtkPolyData |
| 197 | + Triangle with even distirbuted points. |
| 198 | + """ |
| 199 | + |
| 200 | + |
| 201 | + rad = 5 |
| 202 | + img = np.pad(img, ((rad, rad), (rad, rad), (rad, rad))) |
| 203 | + d, h, w = img.shape |
| 204 | + img = skfilters.gaussian(img > 0, sigma=sigma, preserve_range=True) |
| 205 | + imagedata = vtk.vtkImageData() |
| 206 | + imagedata.SetDimensions([w, h, d]) |
| 207 | + imagedata.SetExtent(0, w - 1, 0, h - 1, 0, d - 1) |
| 208 | + imagedata.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) |
| 209 | + values = (255 * img).ravel().astype(np.uint8) |
| 210 | + values = vtknp.numpy_to_vtk(values, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) |
| 211 | + imagedata.GetPointData().SetScalars(values) |
| 212 | + cf = vtk.vtkContourFilter() |
| 213 | + cf.SetInputData(imagedata) |
| 214 | + cf.SetValue(0, 255.0 / np.exp(1.0)) |
| 215 | + cf.Update() |
| 216 | + mesh = cf.GetOutput() |
| 217 | + |
| 218 | + pv_temp = pv.PolyData(mesh) |
| 219 | + cluster = pyacvd.Clustering(pv_temp) |
| 220 | + cluster.cluster(npoints) |
| 221 | + remesh = cluster.create_mesh() |
| 222 | + remesh_vtk = vtk.vtkPolyData() |
| 223 | + remesh_vtk.SetPoints(remesh.GetPoints()) |
| 224 | + remesh_vtk.SetVerts(remesh.GetVerts()) |
| 225 | + remesh_vtk.SetPolys(remesh.GetPolys()) |
| 226 | + return remesh_vtk |
0 commit comments