如何在python中使用ctypes使用intel IPP ippiRemap函数?

问题描述 投票:0回答:1

我正在尝试使用英特尔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

python c++ ctypes intel-ipp
1个回答
0
投票

我只是参考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)
© www.soinside.com 2019 - 2024. All rights reserved.