def decode(src_images, outfile, dark=False, ecc=ECC, fountain=False, force_preprocess=False, deskew=True, auto_dewarp=True): cells = cell_positions(CELL_SPACING, CELL_DIMENSIONS, CELLS_OFFSET) interleave_lookup, block_size = interleave_reverse(cells, INTERLEAVE_BLOCKS, INTERLEAVE_PARTITIONS) dstream = _get_decoder_stream(outfile, ecc, fountain) with dstream as outstream: for imgf in src_images: with interleaved_writer(f=outstream, bits_per_op=BITS_PER_OP, mode='write', keep_open=True) as iw: decoding = { i: bits for i, bits in decode_iter(imgf, dark, force_preprocess, deskew, auto_dewarp) } for i, bits in sorted(decoding.items()): block = interleave_lookup[i] // block_size iw.write(bits, block)
def decode_iter(src_image, dark, force_preprocess, deskew, auto_dewarp): should_preprocess = force_preprocess tempdir = None if deskew: tempdir = TemporaryDirectory() temp_img = path.join(tempdir.name, path.basename(src_image)) dims = detect_and_deskew(src_image, temp_img, dark, auto_dewarp) should_preprocess |= dims[0] < TOTAL_SIZE or dims[1] < TOTAL_SIZE color_img = Image.open(temp_img) else: color_img = Image.open(src_image) ct = CimbDecoder(dark, symbol_bits=BITS_PER_SYMBOL, color_bits=BITS_PER_COLOR) img = _preprocess_for_decode(color_img) if should_preprocess else color_img cell_pos = cell_positions(CELL_SPACING, CELL_DIMENSIONS, CELLS_OFFSET) finder = AdjacentCellFinder(cell_pos, CELL_DIMENSIONS) decode_order = FloodDecodeOrder(cell_pos, finder) for i, (x, y), drift in decode_order: best_bits, best_dx, best_dy, best_distance = _decode_cell( ct, img, color_img, x, y, drift) decode_order.update(best_dx, best_dy, best_distance) yield i, best_bits if tempdir: # cleanup with tempdir: pass
def _decode_iter(ct, img, color_img): cell_pos = cell_positions(CELL_SPACING, CELL_DIMENSIONS, CELLS_OFFSET) finder = AdjacentCellFinder(cell_pos, CELL_DIMENSIONS) decode_order = FloodDecodeOrder(cell_pos, finder) for i, (x, y), drift in decode_order: best_bits, best_dx, best_dy, best_distance = _decode_cell(ct, img, color_img, x, y, drift) decode_order.update(best_dx, best_dy, best_distance) yield i, best_bits
def encode_iter(src_data, ecc, fountain): estream, params = _get_encoder_stream(src_data, ecc, fountain) with estream as instream, bit_file(instream, bits_per_op=bits_per_op(), **params) as f: frame_num = 0 while f.read_count > 0: cells = cell_positions(CELL_SPACING, CELL_DIMENSIONS, CELLS_OFFSET) for x, y in interleave(cells, INTERLEAVE_BLOCKS, INTERLEAVE_PARTITIONS): bits = f.read() yield bits, x, y, frame_num frame_num += 1
def evaluate(src_file, dst_image, dark, force_preprocess, deskew_params): # for byte in src_file, decoded_byte in dst_image: # if mismatch, tally tile information # also track bordering tiles? Edges may matter g = Grader() expected = {(x, y): bits for bits, x, y in encode_iter(src_file, ecc=0)} pos = cell_positions(CELL_SPACING, CELL_DIMENSIONS, CELLS_OFFSET) di = decode_iter(dst_image, dark, force_preprocess, **deskew_params) for i, actual_bits in di: expected_bits = expected[pos[i]] g.grade(expected_bits, actual_bits) g.print_report() return g.error_bits