質問: プログラム初心者です。 以下のコードで表示される画像のWindow名「test1」と「test2」の違いを教えてください。 実行すると表示される画像の質感がわずかに違う感じがします。 ``` import cv2 import numpy as np from time import sleep def test1(path): src1=cv2.imread(path,1) gray=cv2.cvtColor(src1,cv2.COLOR_BGR2GRAY) cv2.imshow('gray',gray) def test2(path): src=cv2.imread(path,0) cv2.imshow('src',src) cv2.waitKey(0) cv2.destroyAllWindows() test1('test.png') print('test1終了') sleep(1) print('test2開始') sleep(1) test2('test.png') ```
回答: test1 はカラー画像で読みこんでから変換する。 test2 は読み込む段階でグレースケールに変換する。 たしかに test1 と test2 は同じ結果になることを期待しますが、微妙に差がありますね。 ``` import cv2 import numpy as np # グレースケールで読み込む。 gray1 = cv2.imread('test.png', cv2.IMREAD_GRAYSCALE) # カラーで読み込んでからグレースケールに変換する。 img = cv2.imread('test.png', cv2.IMREAD_COLOR) gray2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 輝度値の差の平均 print(np.abs(gray1 - gray2).mean()) # 5.248974338347679 ``` グレースケールに変換する計算方法が微妙に違ったりするのでしょうね。 ドキュメントにも一応明記されています。 > > When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available. Results may differ to the output of cvtColor() > > > 意訳 > > cv2.IMREAD_GRAYSCALE でグレースケールとして読み込む場合は、コーデックが提供しているグレースケールの変換機能が利用可能ならそれを使うから、OpenCV が実装しているグレースケールの変換の実装である cvtColor() と結果が違う可能性があるよ。 > > > コーデックというのは、画像を読み書きする外部ライブラリのことです。(libpng, libjpeg, ...) OpenCV: Image file reading and writing 類似の質問もあったので、貼っておきます。 python - Opencv - Grayscale mode Vs gray color conversion - Stack Overflow IMREAD_GRAYSCALE and CV_BGR2GRAY · Issue #10824 · opencv/opencv