2

我正在同时处理几件新事物,因此很难看出我哪里出错了。我是 Android、Kotlin(和 Java)、Renderscript、内核卷积和拉普拉斯算子的新手。

但是我已经设法让 LoG 在 Python 中使用 OpenCV 和 JavaScript 手动工作,并且我已经在 Android 上管理了其他 Renderscript 内部函数。但我无法使用 5x5 convolve 内在函数让 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 通常以有符号浮点数产生输出的事实。如果要显示它,则必须在之后将其标准化为无符号的 8 位整数。

create我尝试使用除U8_4. 有时我会得到奇怪的结果,有时会崩溃。也许 Renderscript 只允许您使用相同的元素类型进行输入和输出?也许只适用于内在?我找不到那个记录。也许我错过了。也许你可以,但我没有设置正确。

我已经尝试对 LoG 使用通常的有符号整数卷积核。如果问题是内核中的负中心元素导致将负值包装为高正值,或者如果乘法溢出或饱和到 255,我尝试“预规范化”我的内核,以便输出始终在范围 0-255。

根据我的尝试,我得到的几乎是白色的位图,对原始位图有淡淡的印象。一些变化会产生平坦的灰色,但乘以放大 LoG 只会改变灰度级。有时输出看起来就像输入一样。

最奇怪的是,起初我的输出位图是输入的副本,这在内部导致了相同的存储。当我这样做时,结果实际上对于我大约一半的测试图像来说是完美的!另一半被破坏了。

那么这对于 5x5 内在函数来说可能是不可能的,但我可以在普通的 Renderscript 中手动完成吗?或者有没有办法从 U8 输入到浮点输出?还是我只是使用与我的位图不兼容的元素类型?或者是通过预规范化来解决它的方法,但我的尝试是错误的?

4

0 回答 0