JSON + CanvasでVisual Code Reading(2)
きのうの続きです。きのうは、img という変数の中身をCanvasで視覚化して、元画像がそのまま格納されていることを確認しました×
今日は、残るsum と sqsum の中身も同様にしてレンダリングしてみました。こんな感じです×
← sum
← sqsum
実際はそれぞれ32bit int型、double型なので、256諧調の中にマップしています×
さて……なんでしょうコレ。この画像(らしきもの)を生成しているコードは以下のような感じです×
for( y = 0; y < size.height; y++, src += srcstep, \ sum += sumstep, sqsum += sqsumstep ) \ { \ sum[-1] = 0; \ sqsum[-1] = 0; \ \ for( x = 0, s = 0, sq = 0; x < size.width; x++ ) \ { \ worktype it = src[x]; \ sumtype t = cast_macro(it); \ sqsumtype tq = cast_sqr_macro(it); \ s += t; \ sq += tq; \ t = sum[x - sumstep] + s; \ tq = sqsum[x - sqsumstep] + sq; \ sum[x] = t; \ sqsum[x] = tq; \ } \ } \
行末に円マーク……じゃなくてバックスラッシュが付いているのは、これがマクロだからです。画像のピクセルの形式に合う関数をマクロでいくつも生成して、実行時にはそのうちの一つが呼び出されます。なので、残念ながらここにはデバッガで入ることができません(C++なんだからテンプレートを使えばいい気もしますが……)×
さて、実はこのマクロの中にさらにマクロが含まれています。それらを展開すると以下のような形になります×
for( y = 0; y < size.height; y++, src += srcstep, \ sum += sumstep, sqsum += sqsumstep ) \ { \ sum[-1] = 0; \ sqsum[-1] = 0; \ \ for( x = 0, s = 0, sq = 0; x < size.width; x++ ) \ { \ int it = src[x]; \ int t = it; \ double tq = icv8x32fSqrTab[(it)+128]; \ s += t; \ sq += tq; \ t = sum[x - sumstep] + s; \ tq = sqsum[x - sqsumstep] + sq; \ sum[x] = t; \ sqsum[x] = tq; \ } \ } \
これは要するに……ピクセルの輝度値を積算しながら、左上から走査しているわけですね。ただし、sum が単純な積算なのに対してsqsum は輝度値を二乗してから足しているようです(icv8x32fSqrTab は、二乗の計算を高速化するためのルックアップテーブルです)×
先ほどの画像と照らし合わせると……なるほど、左上から右下に向かって単調に輝度が増加していますね。sum と sqsum は、元画像の各ピクセルの輝度値の積和を記録した画像、という理解でよさそうです×
さて、問題は、こんな物を何に使うかということですが……
X / _ / X < つづく