@zsh-o
2020-07-16T19:42:46.000000Z
字数 3313
阅读 906
UII
python使用ctypes调用需要注意numpy里面有order的区别,当order为'C'时是按照C的方式排列数据,但其默认为'F',所以使用的时候需要转换,完整调用的例子:
# coding=utf-8
import ctypes
import _ctypes
import numpy as np
import platform
from md.image3d.python.image3d import Image3d
from md.utils.python.find_dll import find_dll
# dynamic library
lib = None
# function pointer dictionary
fun_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_file
def __load_c_functions():
global lib, fun_dict
lib = 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 = None
fun_dict['py_refine_centerline_by_snake'] = lib.py_refine_centerline_by_snake
def unload():
global lib, fun_dict
try:
while lib is not None:
if platform.system() == 'Windows':
_ctypes.FreeLibrary(lib._handle)
else:
_ctypes.dlclose(lib._handle)
except:
lib = None
fun_dict = {}
def load():
unload()
__load_c_functions()
# load dynamic library
load()
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] == 3
cross_section_size = np.array(cross_section_size, dtype=np.int32, order='C')
assert cross_section_size.shape[0] == 2
cross_section_spacing = np.array(cross_section_spacing, dtype=np.float, order='C')
assert cross_section_spacing.shape[0] == 2
refined_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_centerline
if __name__ == "__main__":
import pandas as pd
import numpy as np
import md.image3d.python.image3d_io as cio
path_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)