私は一度にいくつかの新しいことに取り組んでいるので、どこが間違っているのかを見つけるのが難しくなっています. 私は Android、Kotlin (および Java)、Renderscript、カーネル畳み込み、およびラプラシアンを初めて使用します。
しかし、OpenCV と JavaScript を使用して Python で LoG を手動で動作させることができ、Android で他の Renderscript 組み込み関数を管理しました。しかし、5x5 畳み込み組み込み関数を使用して Log を機能させることができません。ここにいくつかのコードがあります:
val bm = BitmapFactory.decodeStream(istr, null, opts)
val bm2 = Bitmap.createBitmap(bm.width, bm.height, bm.config) // ?? Bitmap.Config.ARGB_8888
val rs = RenderScript.create(this@MainActivity)
val conv = ScriptIntrinsicConvolve5x5.create(rs, U8_4(rs)) // ??
val allIn = Allocation.createFromBitmap(rs, bm)
val allOut = Allocation.createFromBitmap(rs, bm2)
val coefs = floatArrayOf(
0f, 0f, 1f, 0f, 0f, // the most standard 5x5 LoG kernel out there
0f, 1f, 2f, 1f, 0f,
1f, 2f, -16f, 2f, 1f,
0f, 1f, 2f, 1f, 0f,
0f, 0f, 1f, 0f, 0f
// attempted "prenormalization"
//0f, 0f, 0.03125f, 0f, 0f,
//0f, 0.03125f, 0.0625f, 0.03125f, 0f,
//0.03125f, 0.0625f, 0.5f, 0.0625f, 0.03125f,
//0f, 0.03125f, 0.0625f, 0.03125f, 0f,
//0f, 0f, 0.03125f, 0f, 0f
)) // ?? .map to "prenormalize" ...
conv.setCoefficients(coefs)
conv.setInput(allIn)
conv.forEach(allOut)
allOut.copyTo(bm2)
私がいくつかのことについて確信が持てないことがわかります。しかし、LoG は通常、符号付き浮動小数点で出力を生成するという事実に帰着する可能性があると思います。表示したい場合は、後で unsigned 8 ビット int に正規化する必要があります。
で、create
以外の要素タイプを使用してみましたU8_4
。奇妙な結果が得られることもあれば、クラッシュすることもあります。Renderscript では、入力と出力に同じ要素タイプしか使用できないのでしょうか? たぶん、組み込み関数のみですか?私はそれが文書化されているのを見つけることができませんでした。多分私はそれを逃した。できるかもしれませんが、正しく設定していません。
通常の署名付き整数畳み込みカーネルを LoG に使用してみました。問題が、カーネルの負の中心要素によって負が高い正にラップされる場合、または乗算がオーバーフローまたは 255 に飽和する場合、カーネルを「事前正規化」して、出力が常に範囲は 0 ~ 255 です。
私が何をしようとしているかにもよりますが、ほとんどの場合、元のビットマップのかすかな印象を持つほとんど白いビットマップが得られます. バリエーションによってはフラット グレーになりますが、乗算して LoG を増幅すると、グレー レベルが変化するだけです。出力が入力と同じように見える場合があります。
最も奇妙なことは、最初は出力ビットマップが入力の複製であり、内部的に同じストレージになったことです。これを行ったとき、結果は実際に私のテスト画像の約半分で完璧でした! 残りの半分は破損していました。
これは 5x5 組み込み関数ではおそらく不可能ですが、プレーンな Renderscript で手動で実行できますか? または、U8 入力から浮動小数点出力に移行する方法はありますか? または、ビットマップと互換性のない要素タイプを使用しているだけですか? または、事前正規化によって修正する方法はありますが、私の試みは間違っていますか?