我正在尝试使用 leptonica 处理后将图像保存为 jpeg。我正在使用带有 ctypes 的 python,我的代码是:
import ctypes
leptlib = "liblept.so"
leptonica = ctypes.cdll.LoadLibrary(leptlib)
filename = "IMAG0724.jpg"
img = leptonica.pixRead(filename)
leptonica.pixConvertTo8.argtypes = [ctypes.c_void_p,
ctypes.c_int32]
pix_image = leptonica.pixConvertTo8(img, False)
leptonica.pixOtsuAdaptiveThreshold.argtypes = [ctypes.c_void_p,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_float]
otsu = leptonica.pixOtsuAdaptiveThreshold(pix_image,20,20,0,0,0.1)
leptonica.pixWriteJpeg.argtypes = [ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_int32,
ctypes.c_int32]
leptonica.pixWriteJpeg("otsu-lept", otsu, 75, 0)
此代码产生错误:
pixWriteJpeg 中的错误:pix 未定义
我相信这是因为我需要在应用 otsu 之后但在编写新图像之前做一些事情。我错过了什么?
编辑-
我现在根据 leptonica 文档http://tpgit.github.io/Leptonica/binarize_8c.html修改了以下内容:
leptonica.pixOtsuAdaptiveThreshold.argtypes = [ctypes.c_void_p,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_float,
ctypes.c_void_p]
leptonica.pixOtsuAdaptiveThreshold(pix_image,20,20,0,0,0.1, img)
leptonica.pixWriteJpeg("otsu-lept", img, 75, 0)
现在出现一个新错误:
支持的最大图像尺寸为 65500 像素 pixWriteStreamJpeg 中的错误:内部 jpeg 错误 pixWriteJpeg 中的错误:pix 未写入流
我的图像分辨率为 1552 x 2592 并且 leptonica.pixWriteJpeg 在 otsu 函数行被注释掉时工作,所以看起来问题仍然在于 otsu 函数返回的图像。
**** 编辑 2 ****
当我使用 leptonica 检查输出 img 时,它告诉我宽度是一个很大的数字,每次运行该函数时似乎都会发生变化(例如 149996048),并且高度在与输入图像相同的值下保持正确。看起来 otsu 函数出于某种原因将图像宽度更改为这个大值。
编辑 3
下面的 jsbueno 为我提供了这个问题的解决方案,我将在这里分享。问题是因为我将图像直接传递给函数,而实际上需要将指针的指针传递给该函数然后才能工作。最终工作代码如下:
import ctypes
leptlib = "liblept.so"
leptonica = ctypes.cdll.LoadLibrary(leptlib)
filename = "IMAG0724.jpg"
img = leptonica.pixRead(filename)
leptonica.pixConvertTo8.argtypes = [ctypes.c_void_p,
ctypes.c_int32
]
pix_image = leptonica.pixConvertTo8(img, False)
w = leptonica.pixGetWidth(img)
h = leptonica.pixGetHeight(img)
pixa_out = leptonica.pixCreate(w,h,8)
pixa = ctypes.c_void_p(pixa_out)
leptonica.pixOtsuAdaptiveThreshold.argtypes = [ctypes.c_void_p,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_int32,
ctypes.c_float,
ctypes.c_void_p,
ctypes.c_void_p
]
otsu = leptonica.pixOtsuAdaptiveThreshold(pix_image,
20,
20,
0,
0,
0.1,
None,
ctypes.addressof(pixa)
)
leptonica.pixWritePng("otsu-lept", pixa, 8)