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

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

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

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

7073閲覧

Python-OpenCVにてjpgファイルの読み込み後、書き出しを行うとファイルサイズが大きくなってしまう。

satake-ze

総合スコア13

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/06/25 06:09

問題点・前提

imread関数であるjpgファイルを読み込み、
imwrite関数でjpgファイルを書き出すと、
書き出し後のjpgのファイルサイズが読み込み元のjpgのファイルサイズより大きくなってしまいます。

具体的には以下の通りです。
読み込み元jpg:1,209KB
書き出し後jpg:1,608KB

異なるいくつかのjpgで試したのですが、
どれも同様の比率でファイルサイズが大きくなってしまいます。

また、読み込み元画像と書き出し後画像の
画素数、画像サイズ、チャンネル数を比較しても全く違いはありませんでした。

背景として、OpenCVを用いて加工対象画像にテキストを乗せて書き出しを行っていたのですが、
ファイルサイズが異常に大きくなってしまっていたため、
試しにimreadの読み込み後、加工処理を行わずimwriteを実行した次第です。

バージョン:
Python3.7.3
OpenCV4.1.0

該当のソースコード

Python

1import cv2 2 3im = cv2.imread('target.jpg') 4cv2.imwrite('after.jpg', im) 5

試したこと

下記を参考に、IMWRITE_JPEG_QUALITYなどjpg書き出し時の設定値をすべて試して書き出したのですが、やはりファイルサイズが大きくなってしまいます。

https://docs.opencv.org/3.4.3/d4/da8/group__imgcodecs.html

また、読み込み元jpgと書き出し後jpgをwinmergeやimagemagickを用いて比較したところ、
確かに大きな差分が確認できるのですが、その原因が何なのか不明な状態です。

上記原因と、ファイルサイズをあまり変えずに書き出す方法をご教授いただけると助かります。
よろしくお願いいたします。

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

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

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

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

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

回答2

0

JPGが「率を指定できる方式で圧縮された画像保存形式」であるためにおきます。

大元の画像を1MBとします。

①大元の画像 1MB

(A率でJPGにして保存)

②taraget.jpg 1.2KB

(読み込み)

③読み込んだ画像 1MB

(B率で③をJPGにして保存)

④after.jpg 1.6KB

こういう流れになっているためです。
ファイルサイズが重要であるならば、tiitoiさんが回答で示されているように
圧縮率(上記の例でいうとB率のところ)を調整しましょう。

ただ、JPGは非可逆圧縮であるため圧縮率をあげる(QUALITYを下げる)と
画像のノイズは当然大きくなります
また、大元の画像からみれば、すでにtarget.jpgになった時点でノイズがのっていて
その上にさらにかけることになる点も注意しましょう。

投稿2019/06/25 13:43

yominet

総合スコア187

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

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

satake-ze

2019/06/26 02:48

なるほど、どういうフローでファイルサイズが大きくなっているのか理解できました! めちゃくちゃ参考になりました、丁寧なご回答ありがとうございます!! 画質よりはファイルサイズのほうが重要なサービスですので、 画質を下げる方向で検討したいと思います! ありがとうございました!m(__)m
guest

0

ベストアンサー

JPEG の圧縮率を imwrite() 関数の第3引数で指定できます。
デフォルトは95になっているので、これを元の画像とファイルサイズが変わらない程度に指定してください。

OpenCV: Image file reading and writing

指定方法は以下のようにします。

python

1import os 2import cv2 3 4img = cv2.imread("sample.jpg") 5cv2.imwrite("output.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 90]) 6 7input_size = os.path.getsize("sample.jpg") 8output_size = os.path.getsize("output.jpg") 9 10print(f"{input_size} -> {output_size}")

quality と出力画像のファイルサイズを調べたら以下のようになりました。
真ん中の水平線が入力画像のファイルサイズです。
quality < 90 ぐらいで入力画像のファイルサイズより出力画像のほうが小さくなりました。(OpenCV のデフォルトは95)

イメージ説明

投稿2019/06/25 11:47

編集2019/06/25 11:56
tiitoi

総合スコア21956

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

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

satake-ze

2019/06/26 02:46

実際のご確認、グラフの添付まで誠にありがとうございます! 画質よりはファイルサイズの方が重要なサービスですので、 qualityを下げる方向で検討したいと思います! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問