2014-09-30 12 views
3

leptonica로 처리 한 후 jpeg로 이미지를 저장하려고합니다. 내가하는 ctypes에 파이썬을 사용하고 내 코드는 다음과 같습니다 난 후 뭔가를 할 필요가 있기 때문에이 믿는 Leptonica - otsu 임계 값 적용 후 이미지를 쓸 수 없습니다.

을 정의되지 PIX : pixWriteJpeg에서

오류 :

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) 

이 코드는 오류가 발생합니다 otsu를 적용했지만 새로운 이미지를 작성하기 전에. 내가 뭘 놓치고 있니?

편집 - 나는 지금 http://tpgit.github.io/Leptonica/binarize_8c.html leptonica 워드 프로세서 당 다음 ammended 한 :

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) 

새로운 오류가 지금 발생

지원되는 최대 이미지 크기는 65,500 픽셀 에 오류가 pixWriteStreamJpeg : 내부 jpeg 오류 pixWriteJpeg의 오류 : pix가 스트림에 쓰여지지 않았습니다.

내 이미지 해상도는 1552 x 2592이며 leptonica.pixWriteJpeg는 otsu 함수 행이 주석 처리 될 때 작동하므로 문제는 otsu 함수가 반환 한 이미지와 여전히 같은 것으로 보입니다.

**** 편집 2 ****

내가 leptonica 사용하여 출력 IMG을 확인

는 폭이 나는 기능을 실행할 때마다 다를 것 같다 일부 많은 나를 말하고있다 (예 : 149,996,048)를 높이는 입력 이미지와 동일한 값으로 유지됩니다. 어떤 이유로 otsu 함수가이 큰 값으로 이미지 너비를 변경하는 것처럼 보입니다.

EDIT 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) 
+1

당신이 유형을 확인할 수 있습니다 : 코드를 따라 뭔가 될 것이라고이 기능을 사용하기위한 -

는 지금처럼, 파이썬 leptonica를 실행할 수 누군가를 위해 (해킹없이 leptonica 1.6.0을 것으로 제한) '오츠 '? pix 코드 포인터가 아니라 오류 코드가있는 int 인 것처럼 보입니다. – 101

+0

예 유형은 int입니다. 고마워, 난 그냥 그게 왜 ctypes.c_void_p를 otsu에 대한 argtypes 목록의 끝에 추가하고 기능을 출력 이미지를 제공하여 이것을 반영하는 기능을 수정했습니다. no는 다른 오류를 리턴합니다. 위 질문에 대한 수정 사항을 참조하십시오. – ajrasp

+0

'pixOtsuAdaptiveThreshold()'는 통과 또는 오류를 반환합니까? 필요한 것보다 하나의 논증이 적은 것처럼 보입니다. – 101

답변

2

-에 대한 배열 중 하나는 - 당신은 함수 서명을 확인하는 경우, 그것은 마지막에 선택적으로 2 muttualy 전용 매개 변수를 이미지가 아닌 계수를 반환합니다. 가장 마지막 매개 변수는 빈 이미지로 알고리즘의 적용을 그릴 수 있습니다.

또한,이 마지막 매개 변수는 leptonica의 PIX 개체의 "포인터에 대한 포인터"입니다 - 당신은 ctypes.c_void_p 객체를 포함하는 파이썬 변수를 생성하고,이 leptonica 함수에 ctypes.addressof를 전달할 수 있습니다.

/*------------------------------------------------------------------* 
*     Adaptive Otsu-based thresholding     * 
*------------------------------------------------------------------*/ 
/*! 
* pixOtsuAdaptiveThreshold() 
* 
*  Input: pixs (8 bpp) 
*    sx, sy (desired tile dimensions; actual size may vary) 
*    smoothx, smoothy (half-width of convolution kernel applied to 
*        threshold array: use 0 for no smoothing) 
*    scorefract (fraction of the max Otsu score; typ. 0.1; 
*       use 0.0 for standard Otsu) 
*    &pixth (<optional return> array of threshold values 
*      found for each tile) 
*    &pixd (<optional return> thresholded input pixs, based on 
*      the threshold array) 
*  Return: 0 if OK, 1 on error 
* 

PS를 다음과 같이 outsu 함수

워드 프로세서이다. 이것을 연구하는 동안, 나는 leptonica 1.7.1을위한 python-leptonica 바인딩을 만들었습니다. 내가 거기에 갔던 엉망을 정리하자마자, 나는 또 다른 릴리즈를 만들어야합니다.

import leptonica 
import ctypes 
img = leptonica.functions.pixRead("t1.png") 
imggray = leptonica.functions.pixConvertRGBToGrayMinMax(img, 1) 
img = leptonica.functions.pixRead("t1.png") 
output = leptonica.functions.pixCreate(imggray.w, imggray.h, 1) 
a = ctypes.c_voidp() 
leptonica.functions.pixOtsuAdaptiveThreshold(imggray, 20, 20, 0, 0, .1, None, ctypes.addressof(a)) 
output = leptonica.PIX(from_address=a) 
leptonica.functions.pixWritePng("t3.png", c, 1) 
+0

대단히 감사합니다! 멋졌지만 아직 작동하지 못했습니다. 나는 argtpyes에 여분의 c_void_p를 추가했고 또한 ctypes.cvoid_p (0)을 함수에 추가했습니다. 새 오류 메시지에 '모듈 객체에 속성이 없습니다. cvoid_p'가 있습니다. 나는 이것이 ctypes.c_void_p (0)로 바뀌었고 이제는 'ctypes.ArgumentError : argument 6 : : 잘못된 유형'이라고 말하여 위의 입력 오류라고 생각합니다. 어떤 생각이 잘못 되었습니까? 다시 한번 감사드립니다. – ajrasp

+0

Ok 나는 실수를 바로 잡았고 실수로 c_float를 삭제했다. 이제 원래 오류가 다시 나타납니다 - "지원되는 최대 이미지 크기는 65500 픽셀입니다. pixWriteStreamJpeg의 오류 : 내부 jpeg 오류 pixWriteJpeg의 오류 : pix가 스트림에 기록되지 않았습니다." 경우에 대비하여 마지막 두 변수의 위치를 ​​전환 해 보았지만 동일한 결과가 발생했습니다. – ajrasp