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

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

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

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

Python

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

Q&A

解決済

2回答

6264閲覧

openCVにおいてグレースケールに変換する際に何が起きているのか。

physics303

総合スコア89

OpenCV

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

Python

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

0グッド

0クリップ

投稿2018/05/14 10:53

編集2018/05/14 10:55

前提

Python3系でopenCVを使ってます。適当な画像をグレースケールに変換する際には、

python

1import cv2 2image = cv2.imread("lena.jpg") 3gly_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

などとすると思います。ここでは、カレントディレクトリにlena画像lena.jpgがあるとしてソースコードを書きました。ここでimageは各ピクセルに(R,G,B)を含むテンソルになっているはずで、実際に

python

1print(image)

とすると、

[[[ 74 111 195]
[ 73 110 194]
[ 75 111 195]
...
[ 30 32 72]
[ 33 34 68]
[ 34 35 63]]

[[ 71 108 192]
[ 72 109 193]
[ 76 112 196]
...
[ 27 28 66]
[ 29 31 62]
[ 30 31 57]]

[[ 73 110 194]
[ 74 110 194]
[ 76 112 196]
...
[ 24 27 58]
[ 29 30 56]
[ 30 31 52]]

...

[[ 50 59 102]
[ 43 54 98]
[ 52 64 112]
...
[ 64 66 100]
[ 57 59 93]
[ 53 54 88]]

[[ 60 69 112]
[ 53 64 108]
[ 48 59 109]
...
[ 62 64 98]
[ 58 61 92]
[ 56 58 89]]

[[ 66 75 118]
[ 60 70 117]
[ 49 60 110]
...
[ 60 63 94]
[ 59 61 92]
[ 60 62 93]]]

というテンソル表現を得ることができます。一方で、gly_imageは各ピクセルに一つの値が割り当てられる行列になっているはずで、実際に

python

1print(gly_image)

とすると、次のような行列表現が得られます。

[[132 131 132 ... 44 44 43]
[129 130 133 ... 39 40 39]
[131 131 133 ... 36 38 37]
...
[ 71 66 77 ... 76 69 64]
[ 81 76 73 ... 74 70 67]
[ 87 83 74 ... 72 70 71]]

疑問

このグレースケールへの変換で何が行われているのでしょうか。OpenCVの公式ページを見ると、グレースケール変換の際には、(R,G,B)は

Y=0.299⋅R+0.587⋅G+0.114⋅B

と変換されるはずです。しかし、うえのlena画像のグレースケール変換前のテンソルとグレースケール変換後の配列の中身を比べると、例えば、1行1列目を見れば、[ 74 111 195]が132になっています。上の公式にあてはめると、

Y=0.29974+0.587111+0.114*195=109.513

なので、132になるのはおかしいのです。
つまり、一見すると、OpenCVの公式ページとは異なる変換が行われているように思えるのですが、これはどういうことでしょうか。

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

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

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

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

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

guest

回答2

0

ベストアンサー

BGRなので

python

1b, g, r = 74, 111, 195 2y = 0.299 * r + 0.587 * g + 0.114 * b 3print(y) # 131.898

と考えると辻褄が合うように思います。

投稿2018/05/14 11:02

KSwordOfHaste

総合スコア18392

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

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

physics303

2018/05/14 11:06

ものすごい恥ずかしいのですが、カラー画像で各ピクセルに割り当てられる数字は(R,G,B)ではなく(B,G,R)なのでしょうか?
KSwordOfHaste

2018/05/14 11:09

COLOR_BGR2GRAY というフラグはもし順番がR,G,Bになっているのであれば COLOR_RGB2GRAY という名前にしただろうと思います。つまりそういうことではないでしょうか。 レナの画像だとわかりにくいですが、真っ赤、真っ青などの単純画像を読み込ませると納得できると思います。多分!
physics303

2018/05/14 11:27

ありがとうございますorz..
guest

0

Pythonはわからないけども、RGBじゃなくBGRだから、
Y=0.299195+0.587111+0.114*74=131.898
な、だけじゃないでしょうか?

投稿2018/05/14 11:01

Wind

総合スコア442

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

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

physics303

2018/05/14 11:06

ものすごい恥ずかしいのですが、カラー画像で各ピクセルに割り当てられる数字は(R,G,B)ではなく(B,G,R)なのでしょうか?
Wind

2018/05/14 11:39

Jpegの様な圧縮ファイルだとわかり辛いですが、 非圧縮なBitmapだと、基本的にB,G,Rの順番で格納されます。 ペイント等で24bitBitmapに変換して、バイナリエディタで画像領域を見ると、 よくわかります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問