ランレングス圧縮を実現させたい
あるデータをランレングス圧縮した後、バイナリ保存してファイル容量を確認してみたら、増加していた。
なにがいけないのかわかりません。
もちろんデータの長さは減っているのですが...
発生している問題
ファイル容量[byte] 25088 0259.yuv(圧縮前) 73680 0259.rle(圧縮後)← 圧縮できていない...
該当のソースコード
読みだしている元データはnumpy配列のバイナリデータです。
python3
1#!/usr/bin/env python3 2import os 3import sys 4import numpy as np 5import argparse 6 7from lib.pyutils import byte2uint 8from lib.pyutils import bd_info 9import toolz as z 10 11 12def encode(s: str) -> str: 13 encoded = [] 14 str_len = len(s) 15 if str_len == 0: 16 return encoded 17 start = 0 18 character = s[0] 19 for i in range(1, str_len): 20 if character != s[i]: 21 diff = i - start 22 _str1 = str(diff)+str(character) 23 encoded.append(diff) 24 encoded.append(character) 25 character = s[i] 26 start = i 27 28 diff_len = str_len - start 29 #_str2 = str(diff_len)+str(character) 30 encoded.append(diff_len) 31 encoded.append(character) 32 33 return encoded 34 35 36def decode(s: str) -> str: 37 str_len = len(s) 38 if str_len == 0: 39 return decoded 40 41 decoded = [s[i+1] for i in range(0, len(s), 2) for j in range(s[i])] 42 43 return decoded 44 45 46def main(): 47 parser = argparse.ArgumentParser( 48 description="Run Length Encoding option") 49 parser.add_argument('--out', '-o', default='result', help='Output directory') 50 51 args = parser.parse_args() 52 53 bitdepth = 8 54 _, bytesize, dtype = bd_info(bitdepth) 55 yuv_file = '0259.yuv' 56 57 #sys.stderr.write("\rcurrent frame {} / {}". format(i+1, len(sorted_file_l))) 58 #yuv_file = os.path.join(yuv_dir, _file) 59 yuv_data = byte2uint(open(yuv_file, 'rb').read(), bytesize, 1) 60 61 #for s in str_list: 62 63 encoded = encode(yuv_data) 64 decoded = decode(encoded) 65 #for a, b in zip(['文字列', '符号化', '復号化', '比較'], 66 # [yuv_data, encoded, decoded, yuv_data == decoded]): 67 for a, b in zip(['比較'], 68 [yuv_data == decoded]): 69 print('{}: {}'. format(a, b)) 70 print(len(yuv_data)) 71 print(len(encoded)) 72 print(len(decoded)) 73 74 suffix = '.rle' 75 path = os.path.join(args.out, str(yuv_file.split('.')[0])) 76 77 a = np.array(encoded) 78 import pdb;pdb.set_trace() 79 with open(path+suffix, 'wb') as f: 80 f.write(np.array(encoded)) 81 np.save(path, encoded) 82 print() 83 84 85if __name__ == '__main__': 86 main()
libのbyte2uint部分です
import time import toolz as z from toolz import curry, pipe from toolz.curried import map as cmap import numpy as np import os import math import struct import json from functools import reduce from operator import add, mul import itertools @curry def byte2uint(byte_stream, byte_size, l=0): if int(byte_size) == 1: f = 'B' dtype = 'u1' elif int(byte_size) == 2: f = 'H' dtype = 'u2' else: raise ValueError("invalid byte_size") t1 = time.time() part = z.partition_all(int(byte_size), byte_stream) barray = [bytearray(i) for i in part] la = [struct.unpack("<"+f, i) for i in barray] var_int = [z.first(i) for i in la] t2 = time.time() print("time is {}". format(t2-t1)) if l: return var_int else: npint8 = np.array(var_int, dtype=dtype) return npint8
試したこと
ちなみに、npyデータで保存した場合は以下になりました。
73808 0259.npy
補足情報(FW/ツールのバージョンなど)
Ubuntu 16.04
python3.5.2
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/01 20:14