[关闭]
@zsh-o 2020-07-16T11:42:46.000000Z 字数 3313 阅读 787

python ctypes

UII


python使用ctypes调用需要注意numpy里面有order的区别,当order为'C'时是按照C的方式排列数据,但其默认为'F',所以使用的时候需要转换,完整调用的例子:

  1. # coding=utf-8
  2. import ctypes
  3. import _ctypes
  4. import numpy as np
  5. import platform
  6. from md.image3d.python.image3d import Image3d
  7. from md.utils.python.find_dll import find_dll
  8. # dynamic library
  9. lib = None
  10. # function pointer dictionary
  11. fun_dict = {}
  12. def __get_library_path():
  13. dll_file = find_dll('py_centerline_snake', __file__, package_name='md_cardiac')
  14. if dll_file is None:
  15. raise OSError('dll not found')
  16. return dll_file
  17. def __load_c_functions():
  18. global lib, fun_dict
  19. lib = ctypes.cdll.LoadLibrary(__get_library_path())
  20. lib.py_refine_centerline_by_snake.argtypes = [
  21. np.ctypeslib.ndpointer(
  22. dtype=ctypes.c_double,
  23. ndim=2,
  24. flags='C_CONTIGUOUS'
  25. ),
  26. ctypes.c_int32,
  27. ctypes.c_double,
  28. ctypes.c_double,
  29. ctypes.c_double,
  30. ctypes.c_double,
  31. ctypes.c_int32,
  32. ctypes.c_void_p,
  33. ctypes.c_char,
  34. np.ctypeslib.ndpointer(
  35. dtype=ctypes.c_int32,
  36. ndim=1,
  37. flags='C_CONTIGUOUS'
  38. ),
  39. np.ctypeslib.ndpointer(
  40. dtype=ctypes.c_double,
  41. ndim=1,
  42. flags='C_CONTIGUOUS'
  43. ),
  44. ctypes.c_bool,
  45. ctypes.c_double,
  46. np.ctypeslib.ndpointer(
  47. dtype=np.float64,
  48. ndim=2,
  49. flags='C_CONTIGUOUS'
  50. )
  51. ]
  52. lib.py_refine_centerline_by_snake.restype = None
  53. fun_dict['py_refine_centerline_by_snake'] = lib.py_refine_centerline_by_snake
  54. def unload():
  55. global lib, fun_dict
  56. try:
  57. while lib is not None:
  58. if platform.system() == 'Windows':
  59. _ctypes.FreeLibrary(lib._handle)
  60. else:
  61. _ctypes.dlclose(lib._handle)
  62. except:
  63. lib = None
  64. fun_dict = {}
  65. def load():
  66. unload()
  67. __load_c_functions()
  68. # load dynamic library
  69. load()
  70. def load_c_functions_if_necesary():
  71. if len(fun_dict) == 0:
  72. print('[info] py_refine_centerline_by_snake dll reloaded')
  73. __load_c_functions()
  74. def call_func(func_name, *args):
  75. load_c_functions_if_necesary()
  76. if len(args) == 0:
  77. return fun_dict[func_name]()
  78. else:
  79. return fun_dict[func_name](*args)
  80. def refine_centerline_by_snake(
  81. centerline,
  82. mask,
  83. multi_label=True,
  84. label=1,
  85. alpha=0.2 * 0.6,
  86. beta=0.5 * 0.6,
  87. gamma=5.0 * 0.6,
  88. omega=0.15,
  89. iters=10,
  90. cross_section_size=[51, 51],
  91. cross_section_spacing=[0.2, 0.2],
  92. max_refinement_distance_in_mm=0.5
  93. ):
  94. assert isinstance(mask, Image3d), 'mask must be an Image3d object'
  95. centerline = np.array(centerline, order='C', dtype=np.float)
  96. assert centerline.shape[1] == 3
  97. cross_section_size = np.array(cross_section_size, dtype=np.int32, order='C')
  98. assert cross_section_size.shape[0] == 2
  99. cross_section_spacing = np.array(cross_section_spacing, dtype=np.float, order='C')
  100. assert cross_section_spacing.shape[0] == 2
  101. refined_centerline = np.zeros_like(centerline, order='C', dtype=np.float)
  102. call_func(
  103. 'py_refine_centerline_by_snake',
  104. np.ascontiguousarray(centerline),
  105. ctypes.c_int32(centerline.shape[0]),
  106. ctypes.c_double(alpha),
  107. ctypes.c_double(beta),
  108. ctypes.c_double(gamma),
  109. ctypes.c_double(omega),
  110. ctypes.c_int32(iters),
  111. mask.ptr,
  112. ctypes.c_char(label),
  113. cross_section_size,
  114. cross_section_spacing,
  115. ctypes.c_bool(multi_label),
  116. ctypes.c_double(max_refinement_distance_in_mm),
  117. refined_centerline
  118. )
  119. return refined_centerline
  120. if __name__ == "__main__":
  121. import pandas as pd
  122. import numpy as np
  123. import md.image3d.python.image3d_io as cio
  124. path_centerline = '/raid/disk/CTA_Cardiac/94_lesion_train/'\
  125. '02_centerline_annotation/0.3mm/AI01_0001_01_L_diast_best_0.50mm/'\
  126. 'SCPR_RCA.csv'
  127. path_mask = '/raid/disk/CTA_Cardiac/02_mask/01_multi_mask_refine/multi_mask/'\
  128. 'AI01_0001_01_L_diast_best_0.50mm.mhd'
  129. df = pd.read_csv(path_centerline)
  130. centerline = np.array(df[['3d_x', '3d_y', '3d_z']].values)
  131. mask = cio.read_image(path_mask, dtype=np.uint8)
  132. refined_centerline = refine_centerline_by_snake(centerline, mask)
  133. print(refined_centerline)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注