3

我正在尝试在 python 中使用 Leptonica (C 库)。该库有一个pixRead将图像文件的绝对路径作为参数的方法。目前我成功地从 python 调用它,如下所示:

leptonica = ctypes.cdll.LoadLibrary("/path/to/lept.so")
pix_image = leptonica.pixRead("/path/to/image.jgp")

但是,我想调用将pixReadStream 文件流作为输入参数的方法。在我的 python 程序中,我可以使用 OpenCV 以 numpy 数组的形式访问图像。

问题

有什么方法可以将我在 Python 程序中作为 numpy 数组的图像传递给pixReadStream将文件流作为输入参数的 leptopnica C 库中的方法?

roi #OpenCV image numpy array
leptonica = ctypes.cdll.LoadLibrary("/path/to/lept.so")
pix_image = leptonica.pixReadStream(##any way to pass roi here?##)
4

3 回答 3

0

从 Numpy 数组创建 LeptonicaPIX结构无需将数据编码为用于存储的图像格式,并以某种方式通过内核将其作为同一进程中的文件传输。将数组数据从 OpenCV 转换为 RGBA 数据,并从 Leptonica 包装足够的数据以创建PIX适当大小的空结构,然后将数组中的数据复制到PIX.

这是一个小示例,如何使用 OpenCV 加载图像,将其转换为包装PIX结构的 Python 对象,然后再次使用 Leptonica 将图像数据保存到文件中:

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from ctypes import c_char_p, c_uint32, c_void_p, CDLL, memmove, pointer, POINTER
from ctypes.util import find_library
import cv2


LEPTONICA = CDLL(find_library('lept'))

_pix_create = LEPTONICA.pixCreate
_pix_create.argtypes = [c_uint32, c_uint32, c_uint32]
_pix_create.restype = c_void_p

_pix_destroy = LEPTONICA.pixDestroy
_pix_destroy.argtypes = [POINTER(c_void_p)]
_pix_destroy.restype = None

_pix_get_data = LEPTONICA.pixGetData
_pix_get_data.argtypes = [c_void_p]
_pix_get_data.restype = POINTER(c_uint32)

_pix_endian_byte_swap = LEPTONICA.pixEndianByteSwap
_pix_endian_byte_swap.argtypes = [c_void_p]
_pix_endian_byte_swap.restype = c_uint32

_pix_write_implied_format = LEPTONICA.pixWriteImpliedFormat
_pix_write_implied_format.argtypes = [c_char_p, c_void_p, c_uint32, c_uint32]
_pix_write_implied_format.restype = c_uint32


class Pix(object):

    def __init__(self, width, height, depth):
        self._as_parameter_ = _pix_create(width, height, depth)
        self._pointer = pointer
        self._pix_destroy = _pix_destroy

    def __del__(self):
        pix_pointer = self._pointer(c_void_p(self._as_parameter_))
        self._pix_destroy(pix_pointer)
        assert pix_pointer[0] is None

    @property
    def data(self):
        return _pix_get_data(self)

    def endian_byte_swap(self):
        _pix_endian_byte_swap(self)

    def save(self, filename, quality=0, progessive=False):
        _pix_write_implied_format(filename, self, quality, progessive)

    @classmethod
    def from_rgba(cls, array):
        width, height, depth = array.shape
        if depth != 4 and array.itemsize != 1:
            raise ValueError('array has wrong format')
        result = cls(width, height, 32)
        memmove(result.data, array.ctypes.data, array.size * array.itemsize)
        result.endian_byte_swap()
        return result


def main():
    image = cv2.imread('test.jpg')
    image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGBA)

    pix = Pix.from_rgba(image)
    pix.save('test.png')


if __name__ == '__main__':
    main()
于 2016-05-18T22:44:43.933 回答
-1
  1. 对于转换,您可以使用 numpy.load 函数... http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.load.html

https://github.com/numpy/numpy/blob/v1.10.1/numpy/lib/npyio.py#L257-L419

  1. 为了与 c 交流...你可以有 ctypes 或 cffi

https://kogs-www.informatik.uni-hamburg.de/~seppke/content/teaching/wise1314/20131107_pridoehl-cffi.pdf

于 2016-04-19T12:49:21.170 回答
-1

可能对你有帮助吗?

给出的答案是“您可以从中使用PyFile_AsFile ”。

于 2016-04-19T06:29:58.230 回答