def find_skew(self): """Returns a tuple (deskew angle in degrees, confidence value). Returns (None, None) if no angle is available. """ with _LeptonicaErrorTrap(): angle = ffi.new('float *', 0.0) confidence = ffi.new('float *', 0.0) result = lept.pixFindSkew(self._cdata, angle, confidence) if result == 0: return (angle[0], confidence[0]) else: return (None, None)
def _repr_png_(self): """iPython display hook returns png version of image """ data = ffi.new('l_uint8 **') size = ffi.new('size_t *') err = lept.pixWriteMemPng(data, size, self._cdata, 0) if err != 0: raise LeptonicaIOError("pixWriteMemPng") char_data = ffi.cast('char *', data[0]) return ffi.buffer(char_data, size[0])[:]
def __getstate__(self): data = ffi.new('l_uint32 **') size = ffi.new('size_t *') err = lept.pixSerializeToMemory(self._cdata, data, size) if err != 0: raise LeptonicaIOError("pixSerializeToMemory") char_data = ffi.cast('char *', data[0]) # Copy from C bytes to python bytes() data_bytes = ffi.buffer(char_data, size[0])[:] # Can now free C bytes lept.lept_free(char_data) return dict(data=data_bytes)
def _destroy(cls, cdata): """Destroy some cdata""" # Leptonica API uses double-pointers for its destroy APIs to prevent # dangling pointers. This means we need to put our single pointer, # cdata, in a temporary CDATA**. pp = ffi.new('{} **'.format(cls.LEPTONICA_TYPENAME), cdata) cls.cdata_destroy(pp)
def generate_pdf_ci_data(self, type_, quality): "Convert to PDF data, with transcoding" p_compdata = ffi.new('L_COMP_DATA **') result = lept.pixGenerateCIData(self._cdata, type_, quality, 0, p_compdata) if result != 0: raise LeptonicaError("Generate PDF data failed") return CompressedData(p_compdata[0])
def write_implied_format(self, path, jpeg_quality=0, jpeg_progressive=0): """Write pix to the filename, with the extension indicating format. jpeg_quality -- quality (iff JPEG; 1 - 100, 0 for default) jpeg_progressive -- (iff JPEG; 0 for baseline seq., 1 for progressive) """ lept_format = lept.getImpliedFileFormat(os.fsencode(path)) with open(path, 'wb') as py_file: data = ffi.new('l_uint8 **pdata') size = ffi.new('size_t *psize') with _LeptonicaErrorTrap(): if lept_format == lept.L_JPEG_ENCODE: lept.pixWriteMemJpeg(data, size, self._cdata, jpeg_quality, jpeg_progressive) else: lept.pixWriteMem(data, size, self._cdata, lept_format) buffer = ffi.buffer(data[0], size[0]) py_file.write(buffer)
def __eq__(self, other): if not isinstance(other, Pix): return NotImplemented same = ffi.new('l_int32 *', 0) with _LeptonicaErrorTrap(): err = lept.pixEqual(self._cdata, other._cdata, same) if err: raise TypeError() return bool(same[0])
def open(cls, path, jpeg_quality=75): "Open compressed data, without transcoding" filename = fspath(path) p_compdata = ffi.new('L_COMP_DATA **') result = lept.l_generateCIDataForPdf(os.fsencode(filename), ffi.NULL, jpeg_quality, p_compdata) if result != 0: raise LeptonicaError("CompressedData.open") return CompressedData(p_compdata[0])
def correlation_binary(pix1, pix2): if get_leptonica_version() < 'leptonica-1.72': # Older versions of Leptonica (pre-1.72) have a buggy # implementation of pixCorrelationBinary that overflows on larger # images. Ubuntu 14.04/trusty has 1.70. Ubuntu PPA # ppa:alex-p/tesseract-ocr has leptonlib 1.75. raise LeptonicaError("Leptonica version is too old") correlation = ffi.new('float *', 0.0) result = lept.pixCorrelationBinary(pix1._cdata, pix2._cdata, correlation) if result != 0: raise LeptonicaError("Correlation failed") return correlation[0]
def otsu_adaptive_threshold( self, tile_size=(300, 300), kernel_size=(4, 4), scorefract=0.1 ): with _LeptonicaErrorTrap(): sx, sy = tile_size smoothx, smoothy = kernel_size p_pix = ffi.new('PIX **') pix = Pix(lept.pixConvertTo8(self._cdata, 0)) result = lept.pixOtsuAdaptiveThreshold( pix._cdata, sx, sy, smoothx, smoothy, scorefract, ffi.NULL, p_pix ) if result == 0: return Pix(p_pix[0]) else: return None
def __setstate__(self, state): cdata_bytes = ffi.new('char[]', state['data']) cdata_uint32 = ffi.cast('l_uint32 *', cdata_bytes) pix = lept.pixDeserializeFromMemory(cdata_uint32, len(state['data'])) Pix.__init__(self, pix)