3

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

今では共有ライブラリとは関係ないようですが、「Pythonで画像データ(配列)を使用する方法」

ありがとう

4

1 に答える 1

1

問題は、ctypes が共有ライブラリ内の関数のシグネチャを認識していないことです。関数を呼び出す前に、ctypes にその署名を知らせる必要があります。ctypes には、これを行うための独自の小さなミニ言語があるため、これは少し面倒です。

cffi を使用することをお勧めします。Cython もオプションですが、C ライブラリをラップするために cython を使用している場合は、面倒なオーバーヘッドが発生することが多く、基本的にまったく新しい言語 (cython) を学習する必要があります。ええ、構文は python に似ていますが、cython のパフォーマンスを理解して最適化するには、私の経験では、生成された C を実際に読み取る必要があります。

cffi (ドキュメント: 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)
于 2013-08-11T21:36:18.767 に答える