def save2binvox(reconstructed_volume, data_name1, data_name2): with open(data_name1, "rb") as f: bvx = brw.read_as_3d_array(f) bvx.dims = [256, 256, 256] bvx.data = reconstructed_volume with open(data_name2, "wb") as f: brw.write(bvx, f)
def voxelizePart(grid, scale, translate, dims, cloud, labels, partId, outputPath): bbmin = np.min(cloud, axis=0) bbmax = np.max(cloud, axis=0) center = 0.5 * (bbmax - bbmin) w1s = np.where(grid == 1) grid_xyz = [[x, y, z] for x, y, z in zip(w1s[0], w1s[1], w1s[2])] grid_xyz = np.array(grid_xyz) grid_xyz_sc = [] for p in grid_xyz: trans_p = [0, 0, 0] trans_p[0] = scale * ((1 / scale) * center[0] - 0.5 + float( (p[0] + 0.5) / dims)) + translate[0] trans_p[1] = scale * ((1 / scale) * center[1] - 0.5 + float( (p[1] + 0.5) / dims)) + translate[1] trans_p[2] = scale * ((1 / scale) * center[2] - 0.5 + float( (p[2] + 0.5) / dims)) + translate[2] grid_xyz_sc.append(trans_p) grid_xyz_sc = np.array(grid_xyz_sc) #grid_xyz_sc is now in the same coordinate frame as the point-cloud clf = knc(n_neighbors=1) clf.fit(cloud, labels) voxelLabels = clf.predict(grid_xyz_sc) partIndices = voxelLabels == partId partVoxelIndices = grid_xyz[partIndices, :] partvox = np.zeros((dims, dims, dims, 1)) partvox[partVoxelIndices[:, 0], partVoxelIndices[:, 2], partVoxelIndices[:, 1], 0] = 1 partvox = partvox.astype('int') partbinvox = binvox_rw.Voxels(partvox, (dims, dims, dims), [0, 0, 0], 1, 'xzy') partname = 'model_' + str(partId) + '.binvox' binvox_rw.write(partbinvox, open(os.path.join(outputPath, partname), 'wb'))
def write_voxel(self, filename): ''' Write the voxel model data into a .binvox file ''' if len(filename) != 0 and not self.isempty(): fp = open(filename, 'w') data = self.voxel > 0 dims = list(self.get_voxel_shape()) translate = [0.0, 0.0, 0.0] scale = 1.0 axis_order = 'xyz' model = binvox_rw.Voxels(data, dims, translate, scale, axis_order) binvox_rw.write(model, fp)
def save_binvox_input_output(input_cloud, mean_voxel, binvox_folder): import binvox_rw import curvox cnn_voxel = shape_completion_utils.round_voxel_grid_to_0_and_1(mean_voxel) partial_vox = curvox.pc_vox_utils.pc_to_binvox_for_shape_completion( points=input_cloud[:, 0:3], patch_size=40) completed_vox = binvox_rw.Voxels(cnn_voxel, partial_vox.dims, partial_vox.translate, partial_vox.scale, partial_vox.axis_order) binvox_rw.write(partial_vox, open(binvox_folder + "network_input.binvox", 'w')) binvox_rw.write(completed_vox, open(binvox_folder + "network_output.binvox", 'w'))
def process_binvox(outfile, res, prediction, fn, idx): # output voxel .binvox file # computer center and scale t = time.time() MIN = np.min(prediction, 0) MAX = np.max(prediction, 0) translate = (MIN + MAX) * 0.5 translate = [float(x) for x in translate] scale = np.max(MAX - MIN) dims = [res, res, res] order = 'xzy' voxel_data = ((prediction - translate) / scale * res + (res - 1.0) / 2.0).T with open(outfile, 'wb') as fout: binvox_rw.write( binvox_rw.Voxels(np.ascontiguousarray(voxel_data), dims, translate, scale, order), fout) print(fn, idx, voxel_data.shape, ' took %f[s]' % (time.time() - t))
def cnn_and_pc_to_mesh(observed_pc, cnn_voxel, filepath, mesh_name, model_pose, log_pc=False, pc_name=""): cnn_voxel = round_voxel_grid_to_0_and_1(cnn_voxel) temp_pcd_handle, temp_pcd_filepath = tempfile.mkstemp(suffix=".pcd") os.close(temp_pcd_handle) pcd = np_to_pcl(observed_pc) pcl.save(pcd, temp_pcd_filepath) partial_vox = curvox.pc_vox_utils.pc_to_binvox_for_shape_completion( points=observed_pc[:, 0:3], patch_size=40) completed_vox = binvox_rw.Voxels(cnn_voxel, partial_vox.dims, partial_vox.translate, partial_vox.scale, partial_vox.axis_order) # Now we save the binvox file so that it can be passed to the # post processing along with the partial.pcd temp_handle, temp_binvox_filepath = tempfile.mkstemp( suffix="output.binvox") os.close(temp_handle) binvox_rw.write(completed_vox, open(temp_binvox_filepath, 'w')) # This is the file that the post-processed mesh will be saved it. mesh_file = file_utils.create_file(filepath, mesh_name) # mesh_reconstruction tmp/completion.binvox tmp/partial.pcd tmp/post_processed.ply # This command will look something like cmd_str = "mesh_reconstruction" + " " + temp_binvox_filepath + " " + temp_pcd_filepath \ + " " + mesh_file + " --cuda" subprocess.call(cmd_str.split(" "), stdout=FNULL, stderr=subprocess.STDOUT) # subprocess.call(cmd_str.split(" ")) if log_pc: pcd_file = file_utils.create_file(filepath, pc_name) cmd_str = "pcl_pcd2ply -format 0" + " " + temp_pcd_filepath + " " + pcd_file subprocess.call(cmd_str.split(" "), stdout=FNULL, stderr=subprocess.STDOUT) map_object_to_gt(pcd_file, model_pose) map_object_to_gt(mesh_file, model_pose)
def main(): if not len(sys.argv) == 2: print('python binvox_converter.py input_file_folder') sys.exit(1) input_file_folder = sys.argv[1] if not os.path.exists(input_file_folder) or not os.path.isdir( input_file_folder): print('[ERROR] Input folder not exists!') sys.exit(2) N_VOX = 32 MESH_EXTENSION = '*.off' folder_path = os.path.join(input_file_folder, MESH_EXTENSION) mesh_files = glob(folder_path) for m_file in mesh_files: file_path = os.path.join(input_file_folder, m_file) file_name, ext = os.path.splitext(m_file) binvox_file_path = os.path.join(input_file_folder, '%s.binvox' % file_name) if os.path.exists(binvox_file_path): print('[WARN] %s File: %s exists. It will be overwritten.' % (dt.now(), binvox_file_path)) os.remove(binvox_file_path) print('[INFO] %s Processing file: %s' % (dt.now(), file_path)) rc = subprocess.call([ 'binvox', '-d', str(N_VOX), '-e', '-cb', '-rotx', '-rotx', '-rotx', '-rotz', m_file ]) if not rc == 0: print('[WARN] %s Failed to convert file: %s' % (dt.now(), m_file)) continue with open(binvox_file_path, 'rb') as file: v = binvox_rw.read_as_3d_array(file) v.data = np.transpose(v.data, (2, 0, 1)) with open(binvox_file_path, 'wb') as file: binvox_rw.write(v, file)
def pcd2binvox(pcd_filepath, binvox_filepath, grid_dim): ''' This function takes a pcd filepath, and converts it to a binvox file. This does not voxeliz the point cloud, it assumes each point can be represented as indices ex cloud: pts = [(0,1,0), (0,10,23), ...] would be converted to a binvox with voxels (0,1,0) and (0 , 10, 23) occupied ''' pc = pcl.load(pcd_filepath) pc_arr = pc.to_array().astype(int) pc_mask = (pc_arr[:,0], pc_arr[:,1], pc_arr[:,2]) out = np.zeros((grid_dim, grid_dim, grid_dim)) out[pc_mask] = 1 out_int = out.astype(int) bv = binvox_rw.Voxels(out_int, out_int.shape, (0,0,0),1, 'xyz') binvox_rw.write(bv, open(binvox_filepath, 'w'))
def write_binvox_file(pred, filename): with open(filename, 'wb+') as f: voxel = binvox_rw.Voxels(pred, [32, 32, 32], [0, 0, 0], 1, 'xzy') binvox_rw.write(voxel, f) f.close()
voxel_model = pcvu.pc_to_binvox_for_shape_completion(pcd_as_np, patch_size) # print(voxel_model) # print(type(voxel_model)) #is a <class 'binvox_rw.binvox_rw.Voxels'> #Vs. saving this method gives a solid version even at 256, but looks low resolution # voxel_model = pcvu.voxelize_points(pcd_as_np, [0,0,0], 1., patch_size, [0,0,0]) # voxel_model = binvox_rw.Voxels(voxel_model, [patch_size,patch_size,patch_size], [0, 0, 0], 0, 'xzy') #bbox_center = [0,0,0] #voxel_resolution = 1. # center = [patch_size/2.,patch_size/2.,patch_size/2.] # voxel_model = pcvu.voxelize_points(pcd_as_np, bbox_center, voxel_resolution, patch_size, center) # voxel_model = binvox_rw.Voxels(voxel_model, [patch_size,patch_size,patch_size], [0,0,0], 0, 'xzy') #Just save out a binvox to look at it and make sure it looks right: #voxel_model = binvox_rw.Voxels(occupancy_3d_array, [resolution, resolution, resolution], [0, 0, 0], 0, 'xzy') test_binvox_path = "/home/gregkocher/Desktop/aaaaaaaaa.binvox" with open(test_binvox_path, 'wb') as fp: binvox_rw.write(voxel_model, fp, fast=True) viewvox_path = '/home/gregkocher/CLionProjects/viewvox/viewvox' test_cmd = '{0} {1}'.format(viewvox_path, test_binvox_path) test_process = subprocess.Popen(test_cmd, shell=True) #Now convert from voxels to octree. #Even if following OGN paper and doing input as 2D image, need the octrees as truth for loss functions. #Using the scripts provided by the OGN paper authors: #10/2/2017 actually the OGN repo does not have working code for this. #Their .../tools/ogn_converter.cpp cannot compile because of various issues. #Their python code does not go binvox->octree, only the reverse direction. #So have to make our own...
def _SaveBinvox(vol, filepath): binvoxvol = binvox_rw.Voxels(vol.voxels, vol.voxels.shape, vol.origin, "%g %g %g" % (vol.voxsize[0], vol.voxsize[1], vol.voxsize[2]), 'xzy') binvox_rw.write(binvoxvol, filepath)
def test(model, model_pose_filepath, partial_view_filepath, completion_filepath, gt_center_to_upright_filepath): pc = pcl.load(partial_view_filepath).to_array() model_pose = np.load(model_pose_filepath) gt_center_to_upright = np.load(gt_center_to_upright_filepath) batch_x = np.zeros( (1, args.PATCH_SIZE, args.PATCH_SIZE, args.PATCH_SIZE, 1), dtype=np.float32) batch_x[ 0, :, :, :, :], voxel_resolution, offset = build_test_from_pc_scaled( pc, args.PATCH_SIZE) mask = get_occluded_voxel_grid(batch_x[0, :, :, :, 0]) #make batch B2C01 rather than B012C batch_x = batch_x.transpose(0, 3, 4, 1, 2) pred = model._predict(batch_x) # Prediction comes in format [batch number, z-axis, patch number, x-axis, # y-axis]. pred = pred.reshape(1, args.PATCH_SIZE, 1, args.PATCH_SIZE, args.PATCH_SIZE) # Convert prediction to format [batch number, x-axis, y-axis, z-axis, # patch number]. pred_as_b012c = pred.transpose(0, 3, 4, 1, 2) completed_region = pred_as_b012c[0, :, :, :, 0] #output is voxel grid from camera_frame of reference. output = completed_region * mask output_vox = output > 0.5 # This is the voxel grid in the camera frame of reference. vox = binvox_rw.Voxels(output > 0.5, (args.PATCH_SIZE, args.PATCH_SIZE, args.PATCH_SIZE), (offset[0], offset[1], offset[2]), voxel_resolution * args.PATCH_SIZE, "xyz") ''' #go from voxel grid back to list of points. #4xn completion = np.zeros((4, len(output_vox.nonzero()[0]))) completion[0] = (output_vox.nonzero()[0] ) * voxel_resolution + offset[0] completion[1] = (output_vox.nonzero()[1] ) * voxel_resolution + offset[1] completion[2] = (output_vox.nonzero()[2] ) * voxel_resolution + offset[2] completion[3] = 1.0 world_to_camera_transform = np.array([[0, 0, 1, -1],[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 0, 1]]) transform = np.dot(model_pose.T, world_to_camera_transform) # 4xn array completion_rot = np.dot(transform, completion).T for i in range(3): completion_rot[:,i] += gt_center_to_upright[i] center = get_center(completion_rot[:,0:3]) pc_center_in_voxel_grid = (20, 20, 20) offset = np.array(center) - np.array(pc_center_in_voxel_grid) * voxel_resolution patch_center_z = (completion_rot[:, 2].max() + completion_rot[:, 2].min())/2.0 patch_center = (0,0,patch_center_z) voxel_grid = create_voxel_grid_around_point_scaled(completion_rot[:,0:3], patch_center, voxel_resolution, args.PATCH_SIZE, (20,20,20)) vox = binvox_rw.Voxels(voxel_grid[:,:,:,0], (args.PATCH_SIZE, args.PATCH_SIZE, args.PATCH_SIZE), (offset[0], offset[1], offset[2]), voxel_resolution * args.PATCH_SIZE, "xyz") ''' #if not os.path.exists(completion_filepath): binvox_rw.write(vox, open(completion_filepath, 'w'))
def _SaveBinvox(vol, filepath): binvoxvol = binvox_rw.Voxels( vol.voxels, vol.voxels.shape, vol.origin, "%g %g %g" % (vol.voxsize[0], vol.voxsize[1], vol.voxsize[2]), 'xzy') binvox_rw.write(binvoxvol, filepath)
def completion_cb(self, goal): rospy.loginfo('Received Completion Goal') self._feedback = pc_pipeline_msgs.msg.CompletePartialCloudFeedback() self._result = pc_pipeline_msgs.msg.CompletePartialCloudResult() temp_pcd_handle, temp_pcd_filepath = tempfile.mkstemp(suffix=".pcd") os.close(temp_pcd_handle) partial_pc_np = curvox.cloud_conversions.cloud_msg_to_np( goal.partial_cloud) pcd = curvox.cloud_conversions.np_to_pcl(partial_pc_np) pcl.save(pcd, temp_pcd_filepath) partial_vox = curvox.pc_vox_utils.pc_to_binvox_for_shape_completion( points=partial_pc_np[:, 0:3], patch_size=self.patch_size) batch_x = np.zeros( (1, self.patch_size, self.patch_size, self.patch_size, 1), dtype=np.float32) batch_x[0, :, :, :, 0] = partial_vox.data if self.flip_batch_x: rospy.loginfo("Flipping Batch X, if performance is poor,\ try setting flip_batch_x=False") batch_x = batch_x.transpose(0, 2, 1, 3, 4) batch_x_new = np.zeros_like(batch_x) for i in range(40): batch_x_new[0, i, :, :, 0] = batch_x[0, 40 - i - 1, :, :, 0] batch_x = batch_x_new else: rospy.loginfo("NOT Flipping Batch X, if performance is poor,\ try setting flip_batch_x=True") # output is the completed voxel grid, # it is all floats between 0,1 as last layer is softmax # think of this as probability of occupancy per voxel # output.shape = (X,Y,Z) output = self.complete_voxel_grid(batch_x) if self.flip_batch_x: rospy.loginfo("flipping batch x back") output_new = np.zeros_like(output) for i in range(40): output_new[i, :, :] = output[40 - i - 1, :, :] output = output_new output = output.transpose(1, 0, 2) # mask the output, so above 0.5 is occupied # below 0.5 is empty space. output_vox = np.array(output) > 0.5 # Save the binary voxel grid as an occupancy map # in a binvox file completed_vox = binvox_rw.Voxels(output_vox, partial_vox.dims, partial_vox.translate, partial_vox.scale, partial_vox.axis_order) # Now we save the binvox file so that it can be passed to the # post processing along with the partial.pcd temp_handle, temp_binvox_filepath = tempfile.mkstemp( suffix="output.binvox") os.close(temp_handle) binvox_rw.write(completed_vox, open(temp_binvox_filepath, 'w')) # Now we save the binvox file so that it can be passed to the # post processing along with the partial.pcd temp_handle, temp_input_binvox_file = tempfile.mkstemp( suffix="input.binvox") os.close(temp_handle) binvox_rw.write(partial_vox, open(temp_input_binvox_file, 'w')) # This is the file that the post-processed mesh will be saved it. temp_handle, temp_completion_filepath = tempfile.mkstemp(suffix=".ply") os.close(temp_handle) # This command will look something like # mesh_reconstruction tmp/completion.binvox tmp/partial.pcd tmp/post_processed.ply cmd_str = self.post_process_executable + " " + temp_binvox_filepath + " " + temp_pcd_filepath \ + " " + temp_completion_filepath + " --cuda" subprocess.call(cmd_str.split(" ")) # Now we are going to read in the post-processed mesh, that is a merge # of the partial view and of the completion from the CNN mesh = curvox.mesh_conversions.read_mesh_msg_from_ply_filepath( temp_completion_filepath) self._result.mesh = mesh self._as.set_succeeded(self._result) rospy.loginfo('Finished Msg')
def align_gt_and_partial(gt_file_path, gt_mesh_file_path, model_pose_filepath, single_view_pointcloud_filepath, model_name, partial_name ): model_pose = np.load(model_pose_filepath) partial_np_pc = load_partial_np_pc(single_view_pointcloud_filepath) gt_np_pc = load_gt_np_pc(gt_file_path) gt_mesh = plyfile.PlyData.read(gt_mesh_file_path) gt_mesh_vertices = np.zeros((gt_mesh['vertex']['x'].shape[0], 4)) gt_mesh_vertices[:, 0] = gt_mesh['vertex']['x'] gt_mesh_vertices[:, 1] = gt_mesh['vertex']['y'] gt_mesh_vertices[:, 2] = gt_mesh['vertex']['z'] partial_np_pc_cf, gt_np_pc_cf, gt_mesh_vertices_cf = map_to_camera_frame( partial_np_pc, gt_np_pc, gt_mesh_vertices, model_pose) partial_np_pc_of, camera_to_object_transform = map_to_object_frame( partial_np_pc, model_pose) gt_mesh['vertex']['x'] = gt_mesh_vertices_cf[:, 0] gt_mesh['vertex']['y'] = gt_mesh_vertices_cf[:, 1] gt_mesh['vertex']['z'] = gt_mesh_vertices_cf[:, 2] partial_pcd_pc_cf = pcl.PointCloud(np.array(partial_np_pc_cf.transpose()[:, 0:3], np.float32)) gt_pcd_pc_cf = pcl.PointCloud(np.array(gt_np_pc_cf.transpose()[:, 0:3], np.float32)) partial_pcd_pc_of = pcl.PointCloud(np.array(partial_np_pc_of.transpose()[:, 0:3], np.float32)) gt_pcd_pc_of = pcl.PointCloud(np.array(gt_np_pc[:, 0:3], np.float32)) result_folder = results_dir + model_name + "/" + partial_name + "/" if not os.path.exists(result_folder): os.makedirs(result_folder) partial_filepath = result_folder + "c_partial.pcd" if not os.path.exists(partial_filepath): pcl.save(partial_pcd_pc_cf, partial_filepath) gt_filepath = result_folder + "c_gt.pcd" if not os.path.exists(gt_filepath): pcl.save(gt_pcd_pc_cf, gt_filepath) partial_filepath_of = result_folder + "c_partial_of.pcd" if not os.path.exists(partial_filepath_of): pcl.save(partial_pcd_pc_of, partial_filepath_of) gt_filepath_of = result_folder + "c_gt_of.pcd" if not os.path.exists(gt_filepath_of): pcl.save(gt_pcd_pc_of, gt_filepath_of) gt_mesh_filepath = result_folder + "c_gt.ply" if True: #not os.path.exists(gt_mesh_filepath): gt_mesh.text = True gt_mesh.write(open(gt_mesh_filepath, "w")) completed_filepath = result_folder + "c_completed.pcd" if not os.path.exists(completed_filepath): completed_pcd_cf, completed_pcd_of, completed_binvox = get_completion(partial_np_pc, camera_to_object_transform) pcl.save(completed_pcd_cf, completed_filepath) pcl.save(completed_pcd_of, completed_filepath.replace(".pcd", "_of.pcd")) binvox_filepath = result_folder + "c_completed.binvox" if not os.path.exists(binvox_filepath): binvox_rw.write(completed_binvox, open(binvox_filepath, 'w')) camera_to_object_transform_filepath = result_folder + "camera_to_object.npy" if not os.path.exists(camera_to_object_transform_filepath): np.save(camera_to_object_transform_filepath, camera_to_object_transform.T)
def AnalyzeOutput_SingleFile(test_ot_path,truth_ot_path,view=True,ignore_truth=False): """ Convert the .ot output file to a binvox file and optionally view the 3d model using viewvox. Also, load the ground truth .ot file to do basic numerical analysis. test_ot_path - path to output .ot file truth_ot_path - path to corresponding ground truth .ot file e.g. test_ot_path = '/home/gregkocher/CLionProjects/ogn/examples/shape_from_id/shapenet_cars_256/output/0065.ot' truth_ot_path = '/home/gregkocher/CLionProjects/ogn/data/shapenet_cars/256_l4/0065.ot' IOU, NMI = AnalyzeOutput_SingleFile(test_ot_path,truth_ot_path,view=True) """ #Load the .ot file that is output from the OGN test net, use the authors' scripts to convert to numpy array #npy_out_path = test_ot_path.replace('.ot','_voxels.npy') ot, resolution = python_octree.import_ot(test_ot_path) output = python_octree.octree_to_voxel_grid(ot, resolution) # print(output) # print(output.sum()) # print(output.size) #np.save(npy_out_path,output) #Now use binvox_rw python module to convert the numpy array to .binvox file occupancy_3d_array = output.astype(np.int) #binvox_rw.Voxels(occupancy_3d_array, data, dims, translate, scale, axis_order) voxel_model = binvox_rw.Voxels(occupancy_3d_array, [resolution, resolution, resolution], [0, 0, 0], 0, 'xzy') #Output as a binvox file test_binvox_path = test_ot_path[:-3] + '.binvox' with open(test_binvox_path,'wb') as fp: binvox_rw.write(voxel_model, fp, fast=True) #binvox_rw.write(voxel_model, fp, fast=False) IOU = None NMI = None if not ignore_truth: #Also load the ground truth .ot file for comparison truth_ot, truth_resolution = python_octree.import_ot(truth_ot_path) truth_output = python_octree.octree_to_voxel_grid(truth_ot, truth_resolution).astype(np.int) #Now use binvox_rw python module to convert the numpy array to .binvox file truth_occupancy_3d_array = truth_output.astype(np.int) #binvox_rw.Voxels(occupancy_3d_array, data, dims, translate, scale, axis_order) truth_voxel_model = binvox_rw.Voxels(truth_occupancy_3d_array, [truth_resolution, truth_resolution, truth_resolution], [0, 0, 0], 0, 'xzy') #Output as a binvox file, put it in the test output dir side by side with test output binvox truth_binvox_path = test_binvox_path.replace('.binvox','_truth.binvox') with open(truth_binvox_path,'wb') as fp: binvox_rw.write(truth_voxel_model, fp, fast=True) #binvox_rw.write(truth_voxel_model, fp, fast=False) #Now do some basic numerical comparisons of output to ground truth: #IOU, Jake's mesh Hausdorff.... #intersection_over_union(gt, pr) IOU = python_octree.intersection_over_union(truth_occupancy_3d_array.flatten(), occupancy_3d_array.flatten()) NMI = metrics.normalized_mutual_info_score(truth_occupancy_3d_array.flatten(), occupancy_3d_array.flatten()) print('IOU', IOU) print('NMI', NMI) #print('AMI', metrics.adjusted_mutual_info_score(truth_occupancy_3d_array.flatten(), occupancy_3d_array.flatten())) #Optionally view the binvox files using viewvox if view: viewvox_path = '/home/gregkocher/CLionProjects/viewvox/viewvox' test_cmd = '{0} {1}'.format(viewvox_path,test_binvox_path) test_process = subprocess.Popen(test_cmd, shell=True) if not ignore_truth: truth_cmd = '{0} {1}'.format(viewvox_path, truth_binvox_path) truth_process = subprocess.Popen(truth_cmd, shell=True) return IOU, NMI
rec.update(recall.item()) for j in xrange(len(f)): modname = mod[j] squence = seq[j] # save .binvox binvox = os.path.join(outdir, modname + '_' + squence + '.binvox') pred = prediction3[j, :, :, :] voxel_data = pred.cpu().data.squeeze().numpy().astype('bool') dims = [64, 64, 64] translate = [0, 0, 0] scale = 1.0 axis_order = 'xzy' with open(binvox, 'wb') as fout: binvox_rw.write( binvox_rw.Voxels(np.ascontiguousarray(voxel_data), dims, translate, scale, axis_order), fout) print( '[%d/%d] mean iou img32: %f , mean iou input32: %f , mean iou input64: %f, precision: %f, recall: %f, time: %f' % (i, len(dataset) / opt.batchSize, iou1.avg, iou2.avg, iou3.avg, pre.avg, rec.avg, time.time() - t0)) iou1.reset() iou2.reset() iou3.reset() pre.reset() rec.reset() network.eval() with torch.no_grad(): for i, data in enumerate(dataloader_test, 0): t0 = time.time()