LoginSignup
1
2

More than 5 years have passed since last update.

Pythonで符号化した画像を復号する

Last updated at Posted at 2018-08-13

この記事で作成した2/4変調符号と言われる符号画像を復号するプログラムを書きました.注意点として,(たぶん)この符号方式は某分野に存在しますがまだ規格化されていたりするわけではないので,わりとオリジナルです.
これです.

revpage.py
import numpy as np
import cv2
import sys

argv = sys.argv
argc = len(argv)


if argc < 2:
    print("利用方法:python revpage.py [basename] [number_of_page] [outputfile]")
    quit()

page_num = int(argv[2])

page_list = []
for i in range(page_num):
    page_list.append(cv2.imread("{0}{1}.png".format(argv[1], i), cv2.IMREAD_GRAYSCALE) > 0)

pix = (page_list[0].shape)[0]
page_max_bits = int((pix ** 2) / 2)


print("ページサイズ:{0}x{0}".format(pix))
print("復号ページ数:{}".format(page_num))
print("復号開始")

read_binary_str = ""
count = 0
for page in range(page_num):
    page_point = page*page_max_bits
    for py in range(int(pix / 2)):
        for px in range(int(pix / 2)):
            # print(binary_str[count*2:(count*2)+2])
            if page_list[page][py*2][px*2+1] == True:
                read_binary_str += '00'
            elif page_list[page][py*2][px*2] == True:
                read_binary_str += '01'
            elif page_list[page][py*2+1][px*2+1] == True:
                read_binary_str += '10'
            elif page_list[page][py*2+1][px*2] == True:
                read_binary_str += '11'

            count += 1

if read_binary_str[-8:] == '11101100':
    code_type = 0
elif read_binary_str[-8:] == '00010001':
    code_type = 1
else:
    code_type = -1

out_binary_str = read_binary_str
for i in range(int(len(read_binary_str)/8)):
    if code_type == 0:
        out_binary_str = out_binary_str[:-8]
        if out_binary_str[-8:] == '00010001':
            code_type = 1
        else:
            code_type = -1
    elif code_type == 1:
        out_binary_str = out_binary_str[:-8]
        if out_binary_str[-8:] == '11101100':
            code_type = 0
        else:
            code_type = -1
    elif code_type == -1:
        if out_binary_str[-8:] == '00000000':
            out_binary_str = out_binary_str[:-8]
            print("復号完了")
            break
        else:
            print("Format error.")
            quit()

with open(argv[3], 'w') as f:
    f.writelines(out_binary_str)

利用法としては,python revpage.py [basename] [number_of_page] [outputfile]です.
basenameは,複数枚に画像がまたがっている場合の,連番を覗いたベースとなる共通ファイル名です.number_of_pageは,複合する連番画像の枚数です.自動で検出するようにしても良かったのですが,重要ではないので(面倒だったので)コマンドラインから渡すことにしました.outputfileは,複合されたバイナリをテキストでダンプするダンプ先ファイルです.

ざっくりとした処理内容

  1. まず,opencvで復号対象の画像ごとにnumpy配列へと読み込みます.それらのnumpy配列はリスト化されて集められています.
  2. 符号化したときの逆の処理を行ってすべての画像を複合し,得られた結果を一つの文字列に連結します.
  3. 後ろについている埋めコードと終了コードを削ります.
  4. ダンプします.

動かしてみる

この記事で作成した,以下の画像を復号します.
stn_page0.png

stn_page1.png

stn_page2.png

stn_page3.png

stn_page4.png

stn_page5.png

これらはstn_page[連番].pngという名前の画像たちです.
python revpage.py stn_page 6 stn_page.binとして復号します.標準出力には以下のような表示がされます.

標準出力
ページサイズ:256x256
復号ページ数:6
復号開始
復号完了

するとこのようなバイナリファイルがダンプされました.
このファイルの2進ダンプデータから,この記事で作成したプログラムでもとのファイルを復元します.

結果,このファイルが完全に復元されました.
stn.jpg

感想

たのしかった

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2