def test_save_image(): chunk = Chunk.create(size=size, dtype=np.uint8, voxel_offset=voxel_offset) tempdir = tempfile.mkdtemp() volume_path = 'file://' + tempdir print('construct volume from numpy array in ', tempdir) vol = CloudVolume.from_numpy(chunk.transpose(), vol_path=volume_path, voxel_offset=voxel_offset[::-1], chunk_size=(32, 32, 4), max_mip=4, layer_type='image') print('construct save operator') op = WritePrecomputedOperator(volume_path, 0, upload_log=True, create_thumbnail=False, name='save') print('really save the chunk.') op(chunk, log={'timer': {'save': 43}}) sleep(2) shutil.rmtree(tempdir)
def test_aligned_input_size(): print('\ntest block inference with aligned input size...') # compute parameters input_size = (18, 224, 224) patch_overlap = (2, 32, 32) input_patch_size = (10, 128, 128) image = Chunk.create(size=input_size, dtype='uint8') with Inferencer(None, None, input_patch_size, num_output_channels=3, output_patch_overlap=patch_overlap, input_size=input_size, framework='identity', dtype='float32') as inferencer: output = inferencer(image) # ignore the cropping region output = output[0, :, :, :] image = image[2:-2, 32:-32, 32:-32] output = output * 255 output = output.astype(np.uint8) assert np.alltrue(np.isclose(image, output, atol=1))
def create_chunk(tasks, name, size, dtype, voxel_offset, output_chunk_name): """Create a fake chunk for easy test.""" print("creating chunk: ", output_chunk_name) for task in tasks: task[output_chunk_name] = Chunk.create(size=size, dtype=np.dtype(dtype), voxel_offset=voxel_offset) yield task
def test_mesh(): ck = Chunk.create(dtype=np.float32) # segment it with threshold ck = ck < 0.5 ck = ck.astype(np.uint32) tempdir = tempfile.mkdtemp() #mesher = MeshOperator('file://' + tempdir, 'precomputed', manifest=True) mesher = MeshOperator('file://' + tempdir, 'obj') mesher(ck) mesher = MeshOperator('file://' + tempdir, 'ply') mesher(ck)
def test_inference(): # compute parameters input_size = (18, 224, 224) patch_overlap = (2, 32, 32) patch_size = (10, 128, 128) image = Chunk.create(size=input_size, dtype='uint8') inference_operator = InferenceOperator(None, None, patch_size=patch_size, output_key='affinity', num_output_channels=3, patch_overlap=patch_overlap, framework='identity') output = inference_operator(image) # ignore the cropping region output = output[0, 2:-2, 32:-32, 32:-32] image = image[2:-2, 32:-32, 32:-32] output = output * 255 output = output.astype(np.uint8) assert np.alltrue(np.isclose(image, output, atol=1))
def __call__(self, input_chunk: np.ndarray): """ args: input_chunk (Chunk): input chunk with global offset """ assert isinstance(input_chunk, Chunk) self._update_parameters_for_input_chunk(input_chunk) output_buffer = self._get_output_buffer(input_chunk) if not self.mask_output_chunk: self._check_alignment() if self.dry_run: print('dry run, return a special artifical chunk.') size = output_buffer.shape if self.mask_myelin_threshold: # eleminate the myelin channel size = (size[0] - 1, *size[1:]) return Chunk.create(size=size, dtype=output_buffer.dtype, voxel_offset=output_buffer.global_offset) if input_chunk == 0: print('input is all zero, return zero buffer directly') if self.mask_myelin_threshold: assert output_buffer.shape[0] == 4 return output_buffer[:-1, ...] else: return output_buffer if np.issubdtype(input_chunk.dtype, np.integer): # normalize to 0-1 value range dtype_max = np.iinfo(input_chunk.dtype).max input_chunk = input_chunk.astype(self.dtype) / dtype_max if self.verbose: chunk_time_start = time.time() # iterate the offset list for i in tqdm(range(0, len(self.patch_slices_list), self.batch_size), disable=not self.verbose, desc='ConvNet inference for patches: '): if self.verbose: start = time.time() batch_slices = self.patch_slices_list[i:i + self.batch_size] for batch_idx, slices in enumerate(batch_slices): self.input_patch_buffer[batch_idx, 0, :, :, :] = input_chunk.cutout( slices[0]).array if self.verbose > 1: end = time.time() print('prepare %d input patches takes %3f sec' % (self.batch_size, end - start)) start = end # the input and output patch is a 5d numpy array with # datatype of float32, the dimensions are batch/channel/z/y/x. # the input image should be normalized to [0,1] output_patch = self.patch_inferencer(self.input_patch_buffer) if self.verbose > 1: assert output_patch.ndim == 5 end = time.time() print('run inference for %d patch takes %3f sec' % (self.batch_size, end - start)) start = end for batch_idx, slices in enumerate(batch_slices): # only use the required number of channels # the remaining channels are dropped # the slices[0] is for input patch slice # the slices[1] is for output patch slice offset = (0, ) + tuple(s.start for s in slices[1]) output_chunk = Chunk(output_patch[batch_idx, :, :, :, :], global_offset=offset) ## save some patch for debug #bbox = output_chunk.bbox #if bbox.minpt[-1] < 94066 and bbox.maxpt[-1] > 94066 and \ # bbox.minpt[-2]<81545 and bbox.maxpt[-2]>81545 and \ # bbox.minpt[-3]<17298 and bbox.maxpt[-3]>17298: # print('save patch: ', output_chunk.bbox) # breakpoint() # output_chunk.to_tif() # #input_chunk.cutout(slices[0]).to_tif() output_buffer.blend(output_chunk) if self.verbose > 1: end = time.time() print('blend patch takes %3f sec' % (end - start)) if self.verbose: print("Inference of whole chunk takes %3f sec" % (time.time() - chunk_time_start)) if self.mask_output_chunk: output_buffer *= self.output_chunk_mask # theoretically, all the value of output_buffer should not be greater than 1 # we use a slightly higher value here to accomondate numerical precision issue np.testing.assert_array_less( output_buffer, 1.0001, err_msg='output buffer should not be greater than 1') if self.mask_myelin_threshold: # currently only for masking out affinity map assert output_buffer.shape[0] == 4 output_chunk = output_buffer.mask_using_last_channel( threshold=self.mask_myelin_threshold) # currently neuroglancer only support float32, not float16 if output_chunk.dtype == np.dtype('float16'): output_chunk = output_chunk.astype('float32') return output_chunk else: return output_buffer