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

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

```python: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. ダンプします．

# 動かしてみる
 [この記事](https://qiita.com/strv13570/items/b899d7c81b0f4f61d904)で作成した，以下の画像を復号します．
![stn_page0.png](https://qiita-image-store.s3.amazonaws.com/0/225893/cbcf02fc-0a5f-63a0-f629-e409dfb90398.png)

![stn_page1.png](https://qiita-image-store.s3.amazonaws.com/0/225893/78378541-b893-ee24-d70f-f631863cc8e1.png)

![stn_page2.png](https://qiita-image-store.s3.amazonaws.com/0/225893/700586c8-cafc-17d2-9bab-a5de045ad4cb.png)

![stn_page3.png](https://qiita-image-store.s3.amazonaws.com/0/225893/80893f59-90ad-e116-7403-09d06d5b7ac6.png)

![stn_page4.png](https://qiita-image-store.s3.amazonaws.com/0/225893/91d61609-a895-bb0e-7e62-701ae91a0b17.png)

![stn_page5.png](https://qiita-image-store.s3.amazonaws.com/0/225893/8d97b661-8114-c0f5-280a-d1c2b828434a.png)

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

```console:標準出力
ページサイズ:256x256
復号ページ数:6
復号開始
復号完了
```
すると[このような](https://raw.githubusercontent.com/strvworks/holopage/master/example/stn_page.bin)バイナリファイルがダンプされました．
このファイルの2進ダンプデータから，[この記事](https://qiita.com/strv13570/items/fb6d5f5dcc0e862b54cd)で作成したプログラムでもとのファイルを復元します．

結果，このファイルが完全に復元されました．
![stn.jpg](https://qiita-image-store.s3.amazonaws.com/0/225893/eb572ec1-67cd-4321-55e2-bcf1ce9cd316.jpeg)

# 感想
たのしかった