web-dev-qa-db-ja.com

OpenCV画像の減算とNumpyの減算

シーン内の動きを想定して、次の画像が前の画像とどれだけ異なるかを追跡しようとしました。 2つのjpg画像間で対応するピクセル値の減算を適用し、結果の行列の平均値を計算して、それが特定のしきい値レベル以下かどうかを確認することを決定しました(詳細な分析用)。

減算はcv2.subtractおよびnp.subtractメソッドによって行われました。結果にはかなり大きな違いがあることに気づきました。 numpyはどういうわけかヒストグラムを伸ばし、結果の値を正規化したようですが、なぜですか?

画像はcv2.open経由で読み込まれました。私はこの方法がチャネルのBGR順序を使用することを知っていますが、何が起こったかを説明しません。ロードされた画像は、np.uint値を持つnumpy nd.arrayです。 Python 3.7。

編集:cv2.imreadの引数0は画像をグレースケールでロードするように指示します

OpenCV減算結果

Numpy減算結果

#loading images

img_cam0 = cv2.imread(r'C:\Users\Krzysztof\Desktop\1.jpg',0)
img_cam1 = cv2.imread(r'C:\Users\Krzysztof\Desktop\2.jpg', 0)
print('img0 type:',type(img_cam0), 'and shape:', img_cam0.shape)
print('img1 type:',type(img_cam1),'and shape:', np.shape(img_cam1))
print('\n')

#opencv subtraction

cv2_subt = cv2.subtract(img_cam0,img_cam1)
cv2_mean = cv2.mean(cv2_subt)

print('open cv mean is:', cv2_mean)
f.show_im(cv2_subt, 'cv2_subtr')

#np subtraction and mean

np_subtr = np.subtract(img_cam0, img_cam1)
np_mean = np.mean(np_subtr)

print('numpy mean is:', np_mean)
f.show_im(np_subtr, 'np_subtr')
6
AnotherLazyPeon

違いは単純です-飽和と飽和なし。

cv2.subtract 飽和を実行します。ドキュメントによると:

dst(I</a loading= saturate(src1(I) - src2(I))">)==

numpy.subtract は通常の減算を実行するだけなので、結果は 整数オーバーフロー の対象になります(つまり、値はラップアラウンドします)。


Saturationは、入力値vがターゲットタイプの範囲外の場合、低を取るだけでは結果が形成されないことを意味します入力のビットですが、代わりに値がクリップされます。例えば:

uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)

このようなクリッピングは、ターゲットタイプがunsigned charsigned charunsigned shortまたはsigned shortの場合に行われます。 32ビット整数の場合、クリッピングは行われません。


>>> import cv2
>>> import numpy as np

>>> a = np.arange(9, dtype=np.uint8).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]], dtype=uint8)
>>> b = np.full((3,3), 4, np.uint8)
>>> b
array([[4, 4, 4],
       [4, 4, 4],
       [4, 4, 4]], dtype=uint8)

>>> np.subtract(b,a)
array([[  4,   3,   2],
       [  1,   0, 255],
       [254, 253, 252]], dtype=uint8)

>>> cv2.subtract(b,a)
array([[4, 3, 2],
       [1, 0, 0],
       [0, 0, 0]], dtype=uint8)
12
Dan Mašek