Image processing RenderScript';s分配输出返回一个黑色位图

Image processing RenderScript';s分配输出返回一个黑色位图,image-processing,allocation,android-bitmap,renderscript,android-renderscript,Image Processing,Allocation,Android Bitmap,Renderscript,Android Renderscript,几天前,我刚刚开始学习RenderScript。我设法创建了一些简单的图像处理过滤器,例如灰度、颜色变化。 现在我正在研究Canny边缘过滤器,但没有成功 问题:为什么ImageView显示黑色图像以及如何解决它? 我正在使用由arekolek制作的Canny egde过滤器的实现 可选:我可以计算得更快吗 最后,我在方法“runEdgeFilter(…)”中编写了所有代码,该方法在我单击设备上的图像时运行,以确保我没有在其他地方干扰imageView。我目前使用的代码 import andro

几天前,我刚刚开始学习RenderScript。我设法创建了一些简单的图像处理过滤器,例如灰度、颜色变化。 现在我正在研究Canny边缘过滤器,但没有成功

问题:为什么ImageView显示黑色图像以及如何解决它?

我正在使用由arekolek制作的Canny egde过滤器的实现

可选:我可以计算得更快吗

最后,我在方法“runEdgeFilter(…)”中编写了所有代码,该方法在我单击设备上的图像时运行,以确保我没有在其他地方干扰imageView。我目前使用的代码

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v8.renderscript.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private static final float THRESHOLD_MULT_LOW = 0.66f * 0.00390625f;
    private static final float THRESHOLD_MULT_HIGH = 1.33f * 0.00390625f;

    private ImageView imageView;
    private Bitmap img;
    private boolean setThresholds = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);
        img = BitmapFactory.decodeResource(getResources(), R.drawable.test_img_no_dpi2);
        imageView.setImageBitmap(img);
    }

    public void imageClicked(View view) {
        runEdgeFilter(img, this);
    }

    private void runEdgeFilter(Bitmap image, Context context) {
        int width = image.getWidth();
        int height = image.getHeight();

        RenderScript rs = RenderScript.create(context);

        Allocation allocationIn = Allocation.createFromBitmap(rs, image);

        Type.Builder tb;

        tb = new Type.Builder(rs, Element.F32(rs)).setX(width).setY(height);
        Allocation allocationBlurred = Allocation.createTyped(rs, tb.create());
        Allocation allocationMagnitude = Allocation.createTyped(rs, tb.create());

        tb = new Type.Builder(rs, Element.I32(rs)).setX(width).setY(height);
        Allocation allocationDirection = Allocation.createTyped(rs, tb.create());
        Allocation allocationEdge = Allocation.createTyped(rs, tb.create());

        tb = new Type.Builder(rs, Element.I32(rs)).setX(256);
        Allocation allocationHistogram = Allocation.createTyped(rs, tb.create());

        tb = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
        Allocation allocationOut = Allocation.createTyped(rs, tb.create());

        ScriptC_edge edgeFilter = new ScriptC_edge(rs);

        ScriptIntrinsicHistogram histogram = ScriptIntrinsicHistogram.create(rs, Element.U8(rs));

        histogram.setOutput(allocationHistogram);

        edgeFilter.invoke_set_histogram(allocationHistogram);
        edgeFilter.invoke_set_blur_input(allocationIn);
        edgeFilter.invoke_set_compute_gradient_input(allocationBlurred);
        edgeFilter.invoke_set_suppress_input(allocationMagnitude, allocationDirection);
        edgeFilter.invoke_set_hysteresis_input(allocationEdge);
        edgeFilter.invoke_set_thresholds(0.2f, 0.6f);

        histogram.forEach_Dot(allocationIn);

        int[] histogramOutput = new int[256];

        allocationHistogram.copyTo(histogramOutput);


        if(setThresholds) {
            int median = width * height / 2;
            for (int i = 0; i < 256; ++i) {
                median -= histogramOutput[i];
                if (median < 1) {
                    edgeFilter.invoke_set_thresholds(i * THRESHOLD_MULT_LOW, i * THRESHOLD_MULT_HIGH);
                    break;
                }
            }
        }

        edgeFilter.forEach_blur(allocationBlurred);
        edgeFilter.forEach_compute_gradient(allocationMagnitude);
        edgeFilter.forEach_suppress(allocationEdge);
        edgeFilter.forEach_hysteresis(allocationOut);

        allocationOut.copyTo(image);

        allocationIn.destroy();
        allocationMagnitude.destroy();
        allocationBlurred.destroy();
        allocationDirection.destroy();
        allocationEdge.destroy();
        allocationHistogram.destroy();
        allocationOut.destroy();
        histogram.destroy();
        edgeFilter.destroy();
        rs.destroy();

        imageView.setImageBitmap(image);
    }
}
返回白色和黑色像素,因此我认为renderscript可以正常工作。 输出与我以前的renderscript过滤器(uchar4)的类型相同,我成功地将其分配给位图。 我不知道我做错了什么

我的logcat还打印:

V/RenderScript_jni: RS compat mode 
V/RenderScript_jni: Unable to load libRSSupportIO.so, USAGE_IO not supported
V/RenderScript_jni: Unable to load BLAS lib, ONLY BNNM will be supported: java.lang.UnsatisfiedLinkError: Couldn't load blasV8 from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.lukasz.edgeexamplers-20.apk,libraryPath=/data/app-lib/com.lukasz.edgeexamplers-20]: findLibrary returned null
E/RenderScript: Couldn't load libRSSupportIO.so
在每个使用renderscript的程序中,但其他程序甚至可以使用此警告

更新#1

正如@Stephen Hines所提到的,阅读越界是有问题的。我想我现在已经通过更改这些行修复了它(没有弄乱renderscript):

edgeFilter.forEach_blur(allocationBlurred);
edgeFilter.forEach_compute_gradient(allocationMagnitude);
edgeFilter.forEach_suppress(allocationEdge);
edgeFilter.forEach_hysteresis(allocationOut);
进入:


但我的问题仍然没有解决。输出和前面一样是黑色的。

一个问题是,您的内核中的“x-1”和“x-2”访问显然超出了范围。您需要夹紧到实际图像的边界才能正确地执行此操作。我没有进一步看,因为你没有解释什么是真正不正确的(或者它只是因为边界问题而对你造成了冲击)。您可以尝试打开调试上下文以获得一些帮助()。就警告日志而言,它们确实是无害的。您不需要BLAS或IO支持。谢谢您的评论。使用
RenderScript rs=RenderScript.create(context,RenderScript.ContextType.DEBUG)未在logcat中添加任何新内容。此外,我还强制renderscript处理修剪过的图像,这将消除边界问题。我假设您使用的是单通道输入位图。在这种情况下,您可能应该调用histogram.forEach()而不是histogram.forEach_Dot(),因为后者会将每个像素乘以默认的红点值0.299f。
V/RenderScript_jni: RS compat mode 
V/RenderScript_jni: Unable to load libRSSupportIO.so, USAGE_IO not supported
V/RenderScript_jni: Unable to load BLAS lib, ONLY BNNM will be supported: java.lang.UnsatisfiedLinkError: Couldn't load blasV8 from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.lukasz.edgeexamplers-20.apk,libraryPath=/data/app-lib/com.lukasz.edgeexamplers-20]: findLibrary returned null
E/RenderScript: Couldn't load libRSSupportIO.so
edgeFilter.forEach_blur(allocationBlurred);
edgeFilter.forEach_compute_gradient(allocationMagnitude);
edgeFilter.forEach_suppress(allocationEdge);
edgeFilter.forEach_hysteresis(allocationOut);
Script.LaunchOptions sLaunchOpt = new Script.LaunchOptions();
sLaunchOpt.setX(2, width - 3);
sLaunchOpt.setY(2, height - 3);
edgeFilter.forEach_blur(allocationBlurred, sLaunchOpt);
edgeFilter.forEach_compute_gradient(allocationMagnitude, sLaunchOpt);
edgeFilter.forEach_suppress(allocationEdge, sLaunchOpt);
edgeFilter.forEach_hysteresis(allocationOut, sLaunchOpt);