def __init__(self, mask: ChunkGrid, verbose=False): self.mask: ChunkGrid[b8] = mask.copy(dtype=b8) self.mask.cleanup(remove=True).pad_chunks(1) self.verbose = verbose self.__mask_chunks_get = self.mask.chunks.get self.min, self.max = self.mask.chunks.minmax(True) self.min -= 1 self.max += 1
def _test_operator2_int(self, op, b0=0, dtype: Type = int, inplace=False): a = ChunkGrid(2, dtype, 0) b = ChunkGrid(2, dtype, 1) a.set_value((0, 0, 0), 1) a.set_value((0, 0, 1), 1) b.set_value((0, 0, 0), 1 + b0) b.set_value((0, 1, 0), 0 + b0) b.set_value((0, 1, 1), 0 + b0) a0 = a.copy() b0 = b.copy() expected = op(a.to_dense(), b.to_dense()) res = op(a, b) self.assertIsInstance(res, ChunkGrid) result = res.to_dense() assert result.shape == expected.shape self.assertTrue(np.all(result == expected), f"Failure {op}! \n{result}\n-------\n{expected}") self._test_inplace_modified(op, a, a0, b, b0, inplace)
def diffuse(model: ChunkGrid[bool], repeat=1): """ Diffuse the voxels in model to their neighboring voxels :param model: the model to diffuse :param repeat: number of diffusion steps :return: diffused model """ kernel = np.zeros((3, 3, 3), dtype=float) kernel[1] = 1 kernel[:, 1] = 1 kernel[:, :, 1] = 1 kernel /= np.sum(kernel) result = ChunkGrid(model.chunk_size, dtype=float, fill_value=1.0) result[model] = 0.0 result.pad_chunks(repeat // result.chunk_size + 1) for r in range(repeat): tmp = result.copy(empty=True) for chunk in result.chunks: padded = chunk.padding(result, 1) ndimage.convolve(padded, kernel, output=padded, mode='constant', cval=1.0) conv = padded[1:-1, 1:-1, 1:-1] m = model.ensure_chunk_at_index(chunk.index, insert=False) if m.is_filled(): if m.value: tmp.ensure_chunk_at_index(chunk.index).set_fill(0.0) continue else: conv[m.to_array()] = 0.0 tmp.ensure_chunk_at_index(chunk.index).set_array(conv) # Expand chunks for f, i in ChunkGrid.iter_neighbors_indices(chunk.index): tmp.ensure_chunk_at_index(i) result = tmp result.cleanup(remove=True) return result