質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2005閲覧

python3 画像のbinary保存 謎

Lizard_knight

総合スコア18

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/05/17 12:53

編集2019/05/18 07:13

python3の画像データのbinary保存の挙動がおかしい。

現在、(622,224,112)の画像をpythonでbinary保存したいと思っています。

発生している問題

binaryデータを読み取った段階で、長さを取得すると、124,838,056と出力されます。 元々、(622,112,224)の画像なので要素数は15,604,736になるはずです。

該当ソースコード

python3

1print(np.array(save_yuv).shape) ### -> (622,112,224)と出力されます。 2 3"""save tiled yuv data """ 4with open(os.path.join(layer_dir, 'stream.yuv'), 'wb') as f: 5 f.write(np.array(save_yuv).flatten())

試したこと

f.write(np.array(save_yuv).flatten())の部分をf.write(np.array(save_yuv))に変更してみた。
結果は同じような124,837,888価でした。
こんなことは初めてなので、pythonにお詳しい方教えてください( ;´Д`)

ちなみに、pickle dumpの方法は正しく動きました。しかし、そのあとに圧縮・展開を行うと、正しくファイルが開けないため、pickle の方法もできません。

それ以外の方法とか何かありますでしょうか。

補足情報(FW/ツールのバージョンなど)

python3.5.2
numpy 1.16.0
サーバー環境
Linux version 4.4.0-142-generic (buildd@lgw01-amd64-033) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

私もいま初めて知ったのですが、numpy配列はbytes-like objectなんですね(ドキュメントの参考項目)。バイナリモードのファイルオブジェクトのwriteの引数に渡せば、そのままバイト列に変換されて吐き出されます。

読み込むなら、

python

1with open("ファイル名", "rb") as f: 2 a = np.frombuffer(f.read(), dtype=もともとの型(画像ならnp.int64かな。確認してみてください)).reshape(622,112,224) 3

とかすればたぶんできます。でも面倒くさいですね。

簡単に扱いたければ、np.savenp.savezがいいのではないでしょうか。

https://docs.scipy.org/doc/numpy/reference/generated/numpy.save.html
https://docs.scipy.org/doc/numpy/reference/generated/numpy.savez.html

投稿2019/05/17 14:21

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lizard_knight

2019/05/18 07:11

回答ありがとうございます! 上記の方法でやってみた結果、要素数は124,837,888でした...
hayataka2049

2019/05/18 07:13

要素数とは? 私のコードではreshapeしているので、あまり関係なさそうですが。
hayataka2049

2019/05/18 07:15

np.array(save_yuv).dtypeを予め見ておき、読み込むときは対応する型を指定する必要があります。その後reshapeすれば元の配列が復元できるかと。
Lizard_knight

2019/05/18 07:17

errorで以下が出力されます。 ValueError: cannot reshape array of size 124837888 into shape (622,112,224)
hayataka2049

2019/05/18 07:22

np.array(save_yuv).dtypeは何で、読み込み時の型には何を指定しましたか?
Lizard_knight

2019/05/18 07:26

保存する前の変数のdtypeがint64であり、実際int8で読み込みたいのでそこが原因だと思います。
Lizard_knight

2019/05/18 07:27

できました!ありがとうございます!!!!
hayataka2049

2019/05/18 07:29

save_yuvはint8で十分表せるということでしょうか? それなら、numpy配列に変換するときに型を指定すれば良いのではないでしょうか。 with open(os.path.join(layer_dir, 'stream.yuv'), 'wb') as f: f.write(np.array(save_yuv, dtype=np.int8).flatten())
hayataka2049

2019/05/18 07:30

とりあえず「この方法でもできる」ことはわかりましたが、私の回答の結論は「np.saveやnp.savezの方が簡単」なので、そちらもよろしければ試してみてください。
Lizard_knight

2019/05/18 08:25

np.save、np.savezの方が確かに楽ですね(笑)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問