mochirism’s blog

日頃のメモが主目的

CUDA版OpenCVで差分絶対値の計算(2)

昨日の続き。 mochirism.hatenablog.com

 既知の値を使ってCPU版とCUDA版で計算結果にどのような違いが出ているのかを確認すれば、この違いが理解できるかもしれないので、1x1行列のオペランド2つで計算させてみる。行列要素の型はVec3bとしてBGRの各要素に

operand1 = [0x02, 0x03, 0x04];

operand2 = [0x01, 0x01, 0x01];

としてGPU版で

  1. abs(subtract(operand1, operand2));
  2. absdiff (operand1, operand2);

の2通りを計算させてみる。

ちなみにCPU版の計算結果(式的には1.に相当)は当然以下の通りとなる。

cpu  result = [0x01, 0x02, 0x03]

 肝心のGPU版の結果は

1. cuda result = [0x00, 0x00, 0x00]

2. cuda result = [0x01, 0x02, 0x03]

 となり、昨日の結果同様に式1.はCPU版の結果と一致せず、式2.のみがCPU版と同じ結果となっている。そこで

  1. subtract(operand1, operan2)

 として計算してみると式1.と同じ結果になった。昨日の

絶対値計算を外すとほぼ同じ結果が得られている様に見えるので、絶対値計算で何か問題発生して違いが出た様子。

CUDA版OpenCVで差分絶対値の計算 - mochirism’s blog

 という結果と異なる結果になったので、再度確認。

すると昨日のこの結果が間違っていて絶対値計算を外しても違う計算結果になっている事が判明。。。という事でsubtract()とabsdiff()では同じ差分を計算していると思っていたが、どうやら違う計算をしている事になる。

ここで何となくオペランドの位置関係が実は想定と逆なのかもしれないと思い、

operand1 = [0x00, 0x01, 0x02];

operand2 = [0x01, 0x01, 0x01];

 として計算させてみると

1. cuda result = [0x01, 0x00, 0x00]

2. cuda result = [0x01, 0x00, 0x01]

 となったので、どうやら式1.は

abs(operand1 - operand2)

ではなく

abs(operand2 - operand1)

と計算しており、非負の型なので負の値は0として処理されているのが異なる結果になる原因っぽい。でabsdiffはどちらから計算したとしても、負の値は0にする前に絶対値変換するので、値は維持されいているという事であろう。

よくよく考えたら画像は非負の値でBGRを表現するので、余りにも当たり前の事であったが、画像の処理になれていなかったので、その事を忘れて符号ありの整数値の想定で考えていたのが敗因であった。