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

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

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

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

Python 3.x

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

解決済

OpenCVを利用して画像をモノクロ&容量削減したいと思ったのですが…

tiqua_nibio
tiqua_nibio

総合スコア62

OpenCV

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

Python 3.x

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

1回答

0評価

1クリップ

168閲覧

投稿2022/09/21 08:09

前提

opencvを使っております。
画像をモノクロ化して、jpegとして保存を行っています。

実現したいこと

・画像のサイズ(xxxピクセル、yyyピクセル)は維持
・圧縮率はできるだけ上げない(拡大したときの画質を維持)
・グレースケールにして、ファイル容量を半分など、できるだけ落とす

発生している問題・エラーメッセージ

opencvで試しては見たのですが、ファイルの容量が下がりません。
おそらく、rgbの数値を入れる配列情報が残ったままになっているのでしょうか。

Photoshopでも同様のことをやってみましたが、グレースケールにして保存すると、ファイルサイズが小さくなっていることが確認できます。
Photoshopでやるような感じで、ファイルサイズを小さくできる方法をご存じであれば、教えていただけないでしょうか?

# ライブラリのインポート import cv2 # 画像の読み込み img = cv2.imread('data/src/lena.jpg') # 読み込んだ画像をグレースケール化 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 画像の保存 cv2.imwrite('/etc/tmp/after_Lena.jpg', img_gray)

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

jbpb0

2022/09/21 22:38 編集

> rgbの数値を入れる配列情報が残ったままになっているのでしょうか。 そうはなってないはずです コードの最後に print(img.shape) print(img_gray.shape) を追加して実行したら分かりますが、「img_gray」は次元が2次元に減ってます(カラー情報が無くなってます) 「cv2.imwrite()」では、データ(numpy配列)のshapeが「(縦, 横)」の場合はグレースケールで、「(縦, 横, 3)」の場合はカラーで保存されますので、「img_gray」を保存した「after_Lena.jpg」は、グレースケール画像のファイルのはずです コードの最後に cv2.imwrite('/etc/tmp/before_Lena.jpg', img) を追加して実行して、カラーのままのデータも保存して、「after_Lena.jpg」と「before_Lena.jpg」のサイズを比べてみてください カラーの「before_Lena.jpg」の方がファイルのサイズが大きくないですか? また、カラーで保存し直しただけの「before_Lena.jpg」は、オリジナルの「lena.jpg」よりもファイルのサイズが大きくないですか?
jbpb0

2022/09/21 23:01 編集

上記のようにして、もし「before_Lena.jpg」の方が「lena.jpg」よりもファイルのサイズが大きいなら、 > 圧縮率はできるだけ上げない が、「圧縮率を下げる」(あまり圧縮しない)になってるのでしょう その場合は、「cv2.imwrite()」で品質を指定して、「before_Lena.jpg」のサイズが「lena.jpg」と同じくらいになれば、圧縮率が「lena.jpg」とだいたい同じになると思いますので、それと同じ品質を指定して保存した「after_Lena.jpg」のサイズは、「lena.jpg」よりも小さくなるでしょう 参考 https://note.nkmk.me/python-opencv-imread-imwrite/ の「cv2.imwrite()で画像ファイルに保存」
tiqua_nibio

2022/09/22 03:08

yohhoyさん ありがとうございます。PYTHON上でコマンドとして実行する分としてはいいですね。 windowsで、mobaxtermの場合、pipなどの問題が絡み、少し扱いにくいように感じました。
tiqua_nibio

2022/09/22 03:12

jbpb0さん >を追加して実行したら分かりますが、「img_gray」は次元が2次元に減ってます(カラー情報が無くなってます) なるほど、確かにファイル容量はすこーしだけ、減少しているのは知っていたのですが、配列も変化はしていたのですね。していないと勘違いしておりました。 >また、カラーで保存し直しただけの「before_Lena.jpg」は、オリジナルの「lena.jpg」よりもファイルのサイズが大きくないですか? これも、デフォルトで圧縮率が30%ぐらいと体感的には感じております。 ですので、圧縮率を50や、95などにすると、やはりもとのファイルよりも容量が大きくなってしまうようですね。 圧縮率について、大小と容量の大小を勘違いしており、すいません。たしかにjbpb0さんの言う通りですね。
jbpb0

2022/09/22 04:20

先に書いたことと重複しますが、解像度(縦横の画素数)を変えずにカラーのままで保存した場合に、元の画像ファイルとサイズがだいたい同じになる「品質」に設定しないと、 > 圧縮率はできるだけ上げない(拡大したときの画質を維持) にはなりません そのように「品質」を設定した上で、グレースケールで保存したら、ファイルのサイズは元画像よりも小さくなるでしょう どんなツールを使おうとも、上記は共通だと思います
ikadzuchi

2022/09/24 18:42

> ファイル容量はすこーしだけ、減少している ということであれば、それが限度なのでしょう。 カラーをグレイスケールにしたところで劇的にファイル容量が少なくなるわけではありません。画像の内容や画質によりますが、せいぜい1割か2割減といったところです。 また、「グレイスケールJPEGで保存した画像」と比べて「カラーJPEGで保存した、内容はグレースケールの画像」は容量はほとんど増えません。試した範囲では2%~4%差でした。 OpenCVでグレイスケールJPEGが利用できないのかは分かりませんが、仮にカラーJPEGで保存されていたとしてもさほど状況に違いはありません。
tiqua_nibio

2022/09/29 05:34

> yohhoyさん ImageMagickツールを試しましたが、やはり小さくならないようです。 > ikadzuchiさん 確かに体感的に1-2割が限度と感じています。
jbpb0

2022/09/29 06:37 編集

opencvでのjpeg保存の「品質」(大きいほど画質がいい=圧縮しない)は、範囲が0〜100で、指定しないと95だそうです 95は上限100に近いので、デフォルト設定では、圧縮はかなり控えめですよね https://tat-pytone.hatenablog.com/entry/2021/04/25/114334 上記Webページの、「品質」を変えて保存した画像ファイルのサイズ比較の表によると、「品質」を80から40に変えたら、ファイルサイズは約半分になってます 「品質」設定は、結構ファイルサイズに効くようです 元画像(lena.jpg)の圧縮が、もし「品質」95よりもかなり小さい(高圧縮)数値相当の圧縮がされてるのなら、それに合わせて「品質」を設定して画像保存しないと、質問者さんが意図してるような結果にはなりませんよね
jbpb0

2022/09/29 06:51 編集

質問者さんが使ってる画像とは違うかもしれませんが、 http://icb-lab.naist.jp/members/yoshi/ouec_lecture/image_recognition/ の「演習教材」の「"Lena" image」の「len_std.jpg」 http://icb-lab.naist.jp/members/yoshi/ouec_lecture/image_recognition/image_files/len_std.jpg をダウンロードして、試してみました 以下、opencvのjpeg保存の「品質」を設定しない場合の、ファイルサイズ(byte)です ・元画像:11888 ・読み込んで保存(カラー):22611 ・読み込んでグレースケール変換して保存:19443 カラーのままでサイズが元画像の2倍くらいになってるので、グレースケールでもまだサイズ大きいですね 「品質」70で保存したら、カラーで保存した場合のファイルサイズがだいたい同じになりました ・元画像:11888 ・読み込んで保存(カラー):11973 ・読み込んでグレースケール変換して保存:10219 グレースケールのサイズは元画像の86%くらいになり、一応サイズは小さくなりましたが、 > 体感的に1-2割が限度と感じています。 ですね
tiqua_nibio

2022/09/29 07:17

情報ありがとうございます。 圧縮率ですが、大体の目安として 幅*高さ*3 とファイルサイズbyteを比較して、大きく離れているほど、圧縮されているという感じのようです。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenCV

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

Python 3.x

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