我正在尝试使用英特尔IPP库共享对象(libipp.so)中的ippiRemap。 通过使用 conda 安装 ipp。
conda install -c intel ipp
库共享对象文件安装在环境目录中。当尝试使用
ippiRemap
函数通过 python 进行图像处理时 ctypes
import ctypes
ipp = ctypes.cdll.loadLibrary('libippi.so')
ippiRemap = ipp.ippiRemap
我收到错误
undefined symbol: ippiRemap
。但是,这可能是由于 C++ 对函数符号名称进行了名称修饰。
尝试 readelf
命令我得到以下输出:
$ readelf -D --symbol /home/user_name/anaconda3/envs/env_name/lib/libippi.so |grep -E "FUNC.*GLOBAL.*ippIRemap.*"
376: 000000000006a180 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16s_AC4R
663: 000000000006a100 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16u_AC4R
685: 000000000006a080 32 FUNC GLOBAL DEFAULT 10 ippiRemap_8u_AC4R
773: 000000000006a120 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16s_C1R
862: 000000000006a140 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16s_C3R
910: 000000000006a020 32 FUNC GLOBAL DEFAULT 10 ippiRemap_8u_C1R
920: 000000000006a160 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16s_C4R
1028: 000000000006a040 32 FUNC GLOBAL DEFAULT 10 ippiRemap_8u_C3R
1079: 000000000006a060 32 FUNC GLOBAL DEFAULT 10 ippiRemap_8u_C4R
1433: 000000000006a200 32 FUNC GLOBAL DEFAULT 10 ippiRemap_32f_AC4R
1794: 000000000006a280 32 FUNC GLOBAL DEFAULT 10 ippiRemap_64f_AC4R
1866: 000000000006a0a0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16u_C1R
1985: 000000000006a0c0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16u_C3R
2049: 000000000006a0e0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_16u_C4R
2424: 000000000006a220 32 FUNC GLOBAL DEFAULT 10 ippiRemap_64f_C1R
2451: 000000000006a1a0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_32f_C1R
2523: 000000000006a240 32 FUNC GLOBAL DEFAULT 10 ippiRemap_64f_C3R
2562: 000000000006a1c0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_32f_C3R
2585: 000000000006a260 32 FUNC GLOBAL DEFAULT 10 ippiRemap_64f_C4R
2615: 000000000006a1e0 32 FUNC GLOBAL DEFAULT 10 ippiRemap_32f_C4R
尝试其中一个符号名称有效。
>> ippiRemap = ipp.ippiRemap_16s_AC4R
>> ippiRemap
<_FuncPtr object at 0x7fc277ba2c80>
所以我的问题是每个符号名称有什么区别,它们的功能相同吗?有没有标准的方法来使用它
ctypes
?
我只是参考intel ipp中ippiRemap函数的文档。我对此没有太多经验。然而,我想分享这个关于如何使用 python 中的 ctypes 与这个函数交互的解决方案。 因此,据我了解 ippiRemap 有几个重载函数(它可能不是我在问题中提到的名称修改)。这是英特尔的文档
所以只要我使用单通道灰度显微图像,我就使用
ippiRemap_8u_C1R
来表示单通道原始major-uint_8图像。
import ctypes
import ctypes.util
ippcore = None
ipp = None
ippi_path = ctypes.util.find_library('ippi')
ippcore_path = ctypes.util.find_library('ippcore')
if ippi_path:
ipp = ctypes.cdll.LoadLibrary(ippi_path)
if ippcore_path:
ippcore = ctypes.cdll.LoadLibrary(ippcore_path)
IPPI_INTER_NN = 1
IPPI_INTER_LINEAR = 3
IPPI_INTER_CUBIC = 6
IPPI_INTER_LANCZOS = 16
#defining c++ structures needed for the function.
#Intel ipp IppiSize c++ structure
class IppiSize(ctypes.Structure):
_fields_ = [('width', ctypes.c_int), ('height', ctypes.c_int)]
#Intel ipp IppiRect c++ structure
class IppiRect(ctypes.Structure):
_fields_ = [
('x', ctypes.c_int),
('y', ctypes.c_int),
('width', ctypes.c_int),
('height', ctypes.c_int)
]
def ippGetStatusString(status):
c_status = ctypes.c_int(status)
c_ippGetStatusString = ippcore.ippGetStatusString
c_ippGetStatusString.argtypes = [
ctypes.c_int
]
c_ippGetStatusString.restype = ctypes.c_char_p
c_status_string = c_ippGetStatusString(c_status)
return c_status_string.decode()
def ippiRemap(src, dst, x_map, y_map, interpolation = IPPI_INTER_NN):
if ipp == None :
raise Exception("Error: libippi library was not found")
# IPPI_INTER_NN: Nearest-neighbor interpolation
# IPPI_INTER_LINEAR: Linear interpolation
# IPPI_INTER_CUBIC: Cubic interpolation
# IPPI_INTER_LANCZOS: Lanczos interpolation
# IPPI_INTER_MITCHELL: Mitchell-Netravali interpolation
c_ippiRemap = getattr(ipp, "ippiRemap_8u_C1R")
#telling ctypes about the c++ function prototype
c_ippiRemap.argtypes = [
ctypes.POINTER(ctypes.c_uint8),
IppiSize,
ctypes.c_int,
IppiRect,
ctypes.POINTER(ctypes.c_float),
ctypes.c_int,
ctypes.POINTER(ctypes.c_float),
ctypes.c_int,
ctypes.POINTER(ctypes.c_uint8),
ctypes.c_int,
IppiSize,
ctypes.c_int
]
c_ippiRemap.restype = ctypes.c_int
c_src_size = IppiSize(src.shape[0], src.shape[1])
c_dst_size = IppiSize(dst.shape[0], dst.shape[1])
x_map_ptr = x_map.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
y_map_ptr = y_map.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
src_ptr = src.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8))
dst_ptr = dst.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8))
src_roi = IppiRect(0, 0, c_src_size.width, c_src_size.height)
dst_roi_size = IppiSize(c_dst_size.width, c_dst_size.height)
x_map_step = ctypes.sizeof(ctypes.c_float)
y_map_step = ctypes.sizeof(ctypes.c_float) * c_src_size.width
status = c_ippiRemap(
src_ptr,
c_src_size,
ctypes.c_int(src.shape[0]),
src_roi,
x_map_ptr,
x_map_step,
y_map_ptr,
y_map_step,
dst_ptr,
ctypes.c_int(dst.shape[0]),
dst_roi_size,
ctypes.c_int(interpolation),
)
if status != 0 : #from Intel ipp documentation non-zero status is a failure
errString = ippGetStatusString(status)
print(errString)