我试图将用c编写的共享库集成到已运行的python应用程序中。为此,我创建了一个简单的.so文件,并尝试访问共享库中编写的函数。
from ctypes import *
import cv2 as cv
import numpy as np
print cv.__version__
so= 'ContrastEnhancement.so'
lib = cdll.LoadLibrary(so)
image = cv.imread('python1.jpg')
image_data = np.array(image)
#calling shared lib function here
lib.ContrastStretch(image_data, width ,height, 5,10)
cv.imwrite("python_result.jpg", )
Traceback (most recent call last):
File "test1.py", line 21, in <module>
lib.ContrastStretch(image_data, width ,height, 5,10)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
如果我试过这个
lib.ContrastStretch(c_uint8(image_data), width ,height, 5,10)
TypeError: only length-1 arrays can be converted to Python scalars
现在好像它与共享lib无关,但'如何在python'中使用图像数据(数组)
感谢 贾韦德
答案 0 :(得分:1)
问题是ctypes不知道共享库中函数的签名。在调用函数之前,你必须让ctypes知道它的签名。这对ctypes来说有点痛苦,因为它有自己的小语言来做这件事。
我建议使用cffi。 Cython也是一个选项,但是如果你只是使用cython来包装c库,那么通常会有很多恼人的开销,你必须基本上学习一种全新的语言(cython)。是的,它在语法上类似于python,但是理解和优化cython性能需要在我的经验中实际读取生成的C语言。
使用cffi(docs:http://cffi.readthedocs.org/en/release-0.7/),您的代码将是这样的:
import cffi
ffi = cffi.FFI()
# paste the function signature from the library header file
ffi.cdef('int ContrastStretch(double* data, int w0 ,int h0, int wf, int hf)
# open the shared library
C = ffi.dlopen('ContrastEnhancement.so')
img = np.random.randn(10,10)
# get a pointer to the start of the image
img_pointer = ffi.cast('double*', img.ctypes.data)
# call a function defined in the library and declared here with a ffi.cdef call
C.ContrastStretch(img_pointer, img.shape[0], img.shape[1], 5, 10)