以下のプログラムで2枚の画像を比較して、一致しない画素値の総数を出力します。
画像のサイズは両方とも256×256です。
なので、画素値の総数は256*256=65,536ですよね?
しかし、プログラムを実行すると、この値を超える数字が出てきます。
これはどこがおかしいのでしょうか?それとも正しいですか?
python
1import cv2 2import numpy as np 3 4# 画像を比較し、一致していない箇所を表示する 5 6# 元画像 7# 単一画像 8img_original = cv2.imread("test3_2D/00109_OUT.png") 9 10#マルチスケール画像 11#r, img_original = cv2.imreadmulti('a.tif', [], cv2.IMREAD_ANYCOLOR) 12 13# 比較対象画像(単一画像) 14img_comparison1 = cv2.imread("MVI354/Target/00109.png") 15#マルチスケール画像 16#r, img_comparison1 = cv2.imreadmulti('a.tif', [], cv2.IMREAD_ANYCOLOR) 17 18# 比較対象画像2枚目(違う画像) 19#r, img_comparison2 = cv2.imreadmulti('b.tif', [], cv2.IMREAD_ANYCOLOR) 20 21#比較画像の画素値が一致しない総数を出力 22print(sum(np.sum(img_original[i] != img_comparison1[i]) for i in range(len(img_comparison1)))) 23#print(sum(np.sum(img_original[i] != img_comparison2[i]) for i in range(len(img_comparison2)))) 24
どういう数字が出てくるんでしょうか
「画素値」というのは、どういう意味で使っていますか?
256*256の画素で構成される画像というのであれば判ります。
また、各画素の色(RGB値)というのであれば、判ります。
「画素値」というのは、一般的に使われる用語なのですか?
対象の画像はカラーで、RGB 単位で比較をしているのだと思います(最大で3倍)。
具体的な数値は70,000~80,000です。
画素値は一般的な意味のピクセルと同義として扱っています。
そうなんですね。比較する2枚の画像は白黒なのですが、それでもRGB単位で処理されますか?
もし白黒画像用に修正するとしたら、どこを修正すれば良いですかね?
白黒なのですね。それでは
print(img_original.shape) と print(img_comparison1.shape) の結果を教えてもらえますか?
(256, 256, 3)
(256, 256, 3)
と出力されました。
ありがとうございます。では
print((img_original != img_comparison1).any(axis=-1).sum())
の結果はどうなりますでしょうか。
16007
と出てきます
はい、それが「一致しない画素値の総数」になります。
?!
ありがとうございます!
僕のプログラムとは何が違うのですか?
白黒専用ですか?
tiroha さんのはすべての要素(256*256*3=196608個)を比較しています。グレースケールとのことですが、カラーチャネルが使われているので画素数よりも大きくなってしまう事があるわけです。わたしのはany(axis=-1) を付ける事で3個のカラーチャネル全体で比較をしています。
3個のカラーチャネル全体で比較とはどういうことでしょうか?
256*256のみを比較ということですか?
はい、その通りです。くどくどとした説明はお嫌いでしょうが、any() は配列内に一つでも True が あれば True を返し、全て False であれば False を返します。この場合では、どれか一つでもカラーチャネルの値が異なっていれば True を、全て同じであれば False になります。
np.array([ True, False, False]).any() => True
np.array([ True, True, False]).any() => True
np.array([False, False, False]).any() => False
.any(axis=-1) を実行すると、256 * 256 の boolean の配列ができる事になります。そして .sum() で最終的な結果を得ることになります。
cv2.imread() は第2引数に cv2.IMREAD_GRAYSCALE を指定しないと、元の画像がグレースケールでも RGB として読み込まれます。
そうなんですね。
ありがとうございます。
回答1件
あなたの回答
tips
プレビュー