Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何为RenderScript输出分配布尔数组?_Android_C_Renderscript - Fatal编程技术网

Android 如何为RenderScript输出分配布尔数组?

Android 如何为RenderScript输出分配布尔数组?,android,c,renderscript,Android,C,Renderscript,我正在尝试优化我的图像处理代码,因为对于大型图像,使用Java处理需要很长时间 我使用DDMS进行了一些方法分析,发现这种方法占用了将近50%的cpu时间: private int getBrightness(int color) { // returns an int from 0-255 where zero is pure black and 255 is pure white, // weighted to correspond to perceived brightne

我正在尝试优化我的图像处理代码,因为对于大型图像,使用Java处理需要很长时间

我使用DDMS进行了一些方法分析,发现这种方法占用了将近50%的cpu时间:

private int getBrightness(int color) {
    // returns an int from 0-255 where zero is pure black and 255 is pure white,
    // weighted to correspond to perceived brightness
    // http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
    int red = Color.red(color);
    int blue = Color.blue(color);
    int green = Color.green(color);
    int brightness = (int) Math.round(Math.sqrt((0.241 * red * red) + (0.691 * green * green) + (0.068 * blue * blue)));
    return brightness;
}
具体来说,对Math.sqrt()和Math.round()的调用才是真正的罪魁祸首。再加上这是串行计算的,而它可以并行完成,这意味着我的处理时间太长了

有人把我指向RenderScript。我觉得这听起来很适合我要做的事情。我知道C++,但不知道C,而且我正努力完成我想要完成的任务。 基本上,在处理时,我不需要知道每个像素的实际亮度,只需要知道它是高于还是低于阈值(在该对象的生命周期内不会改变)。因此,我可以简单地创建一个布尔值数组,告诉我像素是>=阈值(true)还是<阈值(false)。因此,我可以将亮度计算移到renderscript中的C代码中

我想直接将真值或假值返回到输出分配中。这就是我遇到的问题

以下是我的Renderscript C代码:

#pragma version(1)
#pragma rs java_package_name(com.mushroomhouse.pixelbomb)
#pragma rs_fp_relaxed

int threshold = 160;

bool __attribute__((kernel)) generate(uchar4 in) {
    int r = (int) (255*sqrt((float)((0.241 * in.r * in.r) + (0.691 * in.g * in.g) + (0.068 * in.b * in.b))));
    return (r>threshold);
}
下面是我的处理类中的相关代码:

(Member variables)
...
RenderScript myRS;
ScriptC_brightness_map script;
Allocation allocIn, allocOut;
boolean[][] truthMap;

(Public Constructor) {
    ...
    myRS = RenderScript.create(context);
    script = new ScriptC_brightness_map(myRS);    
}

(Initialization before processing is done)
...
truthMap = new boolean[width][height];
allocIn = Allocation.createFromBitmap(myRS, product);
allocOut = ????
script.set_threshold(brightnessValue);
script.forEach_generate(allocIn, allocOut);
...

(Processing)
所以

  • 如何初始化allocOut,我需要一个可以复制到布尔[]的分配

  • 我是否可以立即将allocOut复制到布尔值[][]truthMap,或者我是否需要使用某种回调?我已经读到RenderScript是异步的,所以这会导致问题吗

  • 处理是通过后台的IntentService完成的,因此等待RenderScript不会有问题

    另一个选项是让Renderscript简单地返回计算出的亮度值,我可以在Java代码中进行比较。可能会慢一点,但如果这是唯一可行的方法,我可以接受。但我还是完全不知道怎么做这样的事。关于如何使inAlloc和outAlloc都成为相同尺寸的位图,有很多教程,但我找不到关于不同输出分配的任何内容

    谢谢你的帮助

    两件事

    首先,请记住,根据C99规范,当函数中的浮点常量没有限定符(例如,0.53或类似的东西)时,它们在技术上是双精度的。换句话说,它们的速度很慢。除非你知道你需要双精度,否则你可能不需要它,对于这样简单的图像处理,你肯定不需要它。只要在常数中加上一个f(例如,0.53f),它就会作为一个精度值处理

    您确实需要分配allocOut。最简单的方法是使用Type.Builder。使用
    元素生成二维类型。布尔值
    与位图的尺寸相同。要将其复制回,您需要复制到
    布尔[]
    ,而不是
    布尔[][]
    ,并使用
    truthMap[y*width+x]
    将其索引到其中。IIRC,您可以使用
    copyTo
    将数据放入
    boolean[]
    中,只要其大小是分配的宽度*高度


    如果您不能复制(老实说,我已经忘记了,我很久没有处理Java布尔值了),您可以切换到byte[]和
    元素。U8
    作为RS元素,并写入0或1,而不是false/true。

    感谢您提供有关浮动的提示。我改变了我的方法,我很快就能让它发挥作用。我按照问题末尾的建议做了,让RenderScript返回int foreach并将其复制到int[]brightnessMap中。现在我遇到了一个运行时错误:输入和输出参数之间的维度不匹配
    allocOut=Allocation.createSize(myRS,Element.I32(myRS),brightnessMap.length)所以我想我必须进行2d分配。现在调查一下。感谢您的见解。是的,输入和输出分配必须具有相同的维度(x和y),但我认为允许将2D分配复制到1D Java数组中。