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を表現するので、余りにも当たり前の事であったが、画像の処理になれていなかったので、その事を忘れて符号ありの整数値の想定で考えていたのが敗因であった。

岩波データサイエンス

岩波データサイエンス

こんな本が10/7に発売になるようだ。値段も税込みで1500円とこの手の本にしては高くはないかと思う。vol.1とついているので雑誌なのであろうか?その割には背表紙の幅が厚いように思う。雑誌としても月刊誌なのか?紹介文の最後に

多彩な記事を掲載する予定です

とあるので記事→雑誌、という解釈でもいいような気がする。

内容はベイズ関係の話が載っているのでとりあえずは立ち読みをしてみたい。

 

と思っていたらtwitterのアカウントがあった。

twitter.com

とりあえずシリーズ「岩波データサイエンス」らしい。シリーズというのは岩波では雑誌で使う単語なのだろうか?もう、そこら辺はどうでもいいか。そもそも雑誌の定義がよく分かっていない。

雑誌(ざっし、: Magazine)とは、逐次刊行物であり定期刊行物である出版物の一種。

雑誌 - Wikipedia

という事なので、定期的に出ていれば雑誌という事の様だ。勝手なイメージではシリーズものの本は不定期に発売になる印象があるので、色々よく分からない。

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

OpenCVC++とCUDAで2個の画像間の引き算からの絶対値を計算させていて想定通りの結果にならなかったのでメモ。

C++では

result = abs(image1 - image 2); // 全て変数はMat

として計算させていたので、CUDAでは

cv::cuda::subtract(image1, image2, result);// 全て変数はGpuMat

cv::cuda::abs(result, result);

 として実装してみたら、結果はCPUとCUDAで

f:id:mochirism:20150929235250p:plain

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

(9/30修正:再確認したら絶対値計算を外しても変わらず、差分計算に違いの要因があるようだ)

CUDA版のOpenCVのDocsを調べてみると差分と絶対値を同時に行うcv::cuda::absdiff()なる関数が用意されているので、とりあえずCUDAのコードを

cv::cuda::absdiff(image1, image2, result);

としてみたら、

f:id:mochirism:20150929235601p:plain

とほぼ同じ結果が得られるようになったので、とりあえずめでたしめでたし。。。ではあるのだがこの違いが発生する理由が知りたい。。。。理由として考えられるのは

  • subtract() → abs()とabsdiff()の計算内容がそもそも異なる。
  • abs()の第1、第2引数を同じresultを用いる事に問題がある。

当たりであろうか。。。。

 

ストレスレベルを測りたい

ストレスレベルも計測できるソニーの活動量計SmartBand 2 SWR12。心拍センサー搭載で10月17日発売予定 - Engadget Japanese

ストレスレベルも計測できるという点が個人的にヒットして即予約しようとSONYサイトに行ったのだが、よくよく見るとiOSはアプリがフル機能ではないようなので、ちょっと躊躇している。値段も一万円を超えるので、その点もマイナス材料。

店頭に並んでどんな感じか確認してから買うか確認しよう。AppleTVも新しいの出る事だし。。。

ウェアラブルデバイスの最も大きな障害の一つである常時身に着ける必要がある点がこれも当然ながら解消されておらず、それ自体がストレスの要因になって長続きしないのは使う前から何となくわかっている。

ウェアラブルデバイスは結局、半強制的な健康志向ガジェットとしての位置づけで世間に受け入れられないと普及する事はないのかもしれない。アプリも大ヒットするようなアプリは未だ現れていないし、Apple Watchも持っている人はおっさんが多いとか言われているし、いいイメージより悪いイメージがウェアラブルデバイスに付きまとってしまって、前途多難だな。

function declared with "noreturn" does return

OpenCV 3.0.0をCUDAあり版をビルドして使ってみているのだが、

opencv2/core/base.hpp(342): warning : function declared with "noreturn" does return

という警告がコンパイル時に出てくる。ただし、cuファイルのコンパイルの手前で出ているようなので、書いたコードに問題があるというよりは、何らかのコンパイラの設定に問題があるのだろうか?

 

イマイチ使いこなせていない状況なので警告に意味が分からないので、放置でOKなのかどうかが判断つかない。

CUDAの本

 

CUDA C プロフェッショナル プログラミング (impress top gear)

CUDA C プロフェッショナル プログラミング (impress top gear)

 

 ちょっと時間を見つけて立ち読みしてみたい。