@zsh-o
2020-07-16T11:42:46.000000Z
字数 3313
阅读 1114
UII
python使用ctypes调用需要注意numpy里面有order的区别,当order为'C'时是按照C的方式排列数据,但其默认为'F',所以使用的时候需要转换,完整调用的例子:
# coding=utf-8import ctypesimport _ctypesimport numpy as npimport platformfrom md.image3d.python.image3d import Image3dfrom md.utils.python.find_dll import find_dll# dynamic librarylib = None# function pointer dictionaryfun_dict = {}def __get_library_path():dll_file = find_dll('py_centerline_snake', __file__, package_name='md_cardiac')if dll_file is None:raise OSError('dll not found')return dll_filedef __load_c_functions():global lib, fun_dictlib = ctypes.cdll.LoadLibrary(__get_library_path())lib.py_refine_centerline_by_snake.argtypes = [np.ctypeslib.ndpointer(dtype=ctypes.c_double,ndim=2,flags='C_CONTIGUOUS'),ctypes.c_int32,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_int32,ctypes.c_void_p,ctypes.c_char,np.ctypeslib.ndpointer(dtype=ctypes.c_int32,ndim=1,flags='C_CONTIGUOUS'),np.ctypeslib.ndpointer(dtype=ctypes.c_double,ndim=1,flags='C_CONTIGUOUS'),ctypes.c_bool,ctypes.c_double,np.ctypeslib.ndpointer(dtype=np.float64,ndim=2,flags='C_CONTIGUOUS')]lib.py_refine_centerline_by_snake.restype = Nonefun_dict['py_refine_centerline_by_snake'] = lib.py_refine_centerline_by_snakedef unload():global lib, fun_dicttry:while lib is not None:if platform.system() == 'Windows':_ctypes.FreeLibrary(lib._handle)else:_ctypes.dlclose(lib._handle)except:lib = Nonefun_dict = {}def load():unload()__load_c_functions()# load dynamic libraryload()def load_c_functions_if_necesary():if len(fun_dict) == 0:print('[info] py_refine_centerline_by_snake dll reloaded')__load_c_functions()def call_func(func_name, *args):load_c_functions_if_necesary()if len(args) == 0:return fun_dict[func_name]()else:return fun_dict[func_name](*args)def refine_centerline_by_snake(centerline,mask,multi_label=True,label=1,alpha=0.2 * 0.6,beta=0.5 * 0.6,gamma=5.0 * 0.6,omega=0.15,iters=10,cross_section_size=[51, 51],cross_section_spacing=[0.2, 0.2],max_refinement_distance_in_mm=0.5):assert isinstance(mask, Image3d), 'mask must be an Image3d object'centerline = np.array(centerline, order='C', dtype=np.float)assert centerline.shape[1] == 3cross_section_size = np.array(cross_section_size, dtype=np.int32, order='C')assert cross_section_size.shape[0] == 2cross_section_spacing = np.array(cross_section_spacing, dtype=np.float, order='C')assert cross_section_spacing.shape[0] == 2refined_centerline = np.zeros_like(centerline, order='C', dtype=np.float)call_func('py_refine_centerline_by_snake',np.ascontiguousarray(centerline),ctypes.c_int32(centerline.shape[0]),ctypes.c_double(alpha),ctypes.c_double(beta),ctypes.c_double(gamma),ctypes.c_double(omega),ctypes.c_int32(iters),mask.ptr,ctypes.c_char(label),cross_section_size,cross_section_spacing,ctypes.c_bool(multi_label),ctypes.c_double(max_refinement_distance_in_mm),refined_centerline)return refined_centerlineif __name__ == "__main__":import pandas as pdimport numpy as npimport md.image3d.python.image3d_io as ciopath_centerline = '/raid/disk/CTA_Cardiac/94_lesion_train/'\'02_centerline_annotation/0.3mm/AI01_0001_01_L_diast_best_0.50mm/'\'SCPR_RCA.csv'path_mask = '/raid/disk/CTA_Cardiac/02_mask/01_multi_mask_refine/multi_mask/'\'AI01_0001_01_L_diast_best_0.50mm.mhd'df = pd.read_csv(path_centerline)centerline = np.array(df[['3d_x', '3d_y', '3d_z']].values)mask = cio.read_image(path_mask, dtype=np.uint8)refined_centerline = refine_centerline_by_snake(centerline, mask)print(refined_centerline)