バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia3-backnumber/
はじめに
グレースケール化処理を各ツール、各言語で実施。
今回はPython(NumPy)で実施する。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
使用する画像

まずは、使用する画像を再掲。

ファイル名はdog.jpgとする。

今回は、Python(NumPy)によるグレースケール化の実施
Pythonコード

Pythonコードは以下になる。
import numpy as np
import cv2
# 入力画像の読み込み
img = cv2.imread("dog.jpg")
b = img[:,:,0]
g = img[:,:,1]
r = img[:,:,2]
# RGB平均グレースケール
gray_ave = np.array(r/3 + g/3 + b/3, dtype='uint8')
# グレースケール画像の書き込み
cv2.imwrite("dog_gray_ave.jpg", gray_ave)
# SDTVグレースケール
gray_sdtv = np.array(0.2990 * r + 0.5870 * g + 0.1140 * b, dtype='uint8')
# グレースケール画像の書き込み
cv2.imwrite("dog_gray_sdtv.jpg", gray_sdtv)
gray_cv = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("dog_gray_ocv.jpg", gray_cv)
処理結果

そして処理結果。
dog_gray_ave.jpg(RBG平均)

dog_gray_sdtv.jpg(SDTV)

dog_gray_ocv.jpg(OpenCV)

考察

あれ?Pythonでは、3つのグレースケールをやってるね?
最後のはOpenCVによるグレースケール?

一撃でグレースケール化できそうだったんで追加した。
OpenCVのグレースケールはSDTVらしいが、完全一致という感じではなかったな。
これはOpenCVのドキュメントにそれらしいことが書いてあった。
When using IMREAD_GRAYSCALE, the codec’s internal grayscale conversion will be used, if available. Results may differ to the output of cvtColor()
https://docs.opencv.org/4.7.0/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56
↓日本語訳
IMREAD_GRAYSCALE を使用する場合、コーデック内部のグレースケールコンバージョンが使用されます(使用可能な場合)。結果は、cvtColor()の出力と異なる場合があります。
https://docs.opencv.org/4.7.0/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56

なるほど・・・。
これはいろいろ沼な感じがするな・・・。

まぁ、ここはあまり踏み込まず、こういう情報があるって程度で留めておいた方が良いだろう。

あとは、np.arrayで画像データを定義する際にdtype=’uint8’を指定しているのは1チャンネル1ピクセル辺りのデータ長が8bitだからか。

そうそう。
まとめ

まとめだよ。
- Python(NumPy)でRGB平均とSDTVのグレースケール化実施。
- 次いでにOpenCVによるグレースケール化も。
- OpenCVによるグレースケール化はコーデック依存な面がある。
- 画像データはの1チャンネル1ピクセルは8bit長。
バックナンバーはこちら。
コメント