- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试优化我的图像处理代码,因为对于大型图像,使用 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,而且我很难完成我想要完成的事情。
基本上,在处理时我不需要知道每个像素的实际亮度,只需要知道它是高于还是低于阈值(在该对象的生命周期内不会改变)。所以我可以简单地创建一个 bool 值数组,告诉我像素是 >= 阈值 (true) 还是 < 阈值 (false)。所以我可以将亮度计算移至渲染脚本中的 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,我需要一个可以复制到 boolean[][] 的分配。
我可以立即将 allocOut 复制到我的 boolean[][] truthMap 还是我需要使用某种回调?我读到 RenderScript 是异步的,这会导致问题吗?
处理是通过后台的 IntentService 完成的,因此等待 RenderScript 不会有问题。
另一种选择是让 Renderscript 简单地返回计算出的亮度值,我可以在 Java 代码中进行比较。可能会慢一点,但如果这是唯一可行的方法,我可以接受。但是我仍然完全不知道如何做这样的事情。关于如何使 inAlloc 和 outAlloc 成为相同尺寸的位图的教程很多,但我找不到关于不同输出分配的任何内容。
感谢您的帮助!
最佳答案
一些事情。
首先,请记住,根据 C99 规范,当您在没有限定符(例如 0.53 或类似的东西)的函数中使用浮点常量时,它们在技术上是 double 的。换句话说,它们慢。除非你知道你需要 double ,否则你可能不需要它,对于像这样的简单图像处理,你绝对不需要它。只需将 f 添加到常量(例如 0.53f),它将作为单精度值处理。
您确实需要 allocOut 的分配。最简单的方法是使用 Type.Builder。使用与位图尺寸相同的 Element.BOOLEAN
构建二维类型。要将其复制回来,您需要复制到 boolean[]
,而不是 boolean[][]
,并使用 truthMap[y * width] 对其进行索引+ x]
。 IIRC,您可以使用 copyTo
将数据获取到 boolean[]
中,只要它的大小是分配的宽度 * 高度。
如果你不能复制(老实说我忘记了,我已经很长时间没有处理 Java bool 值了),你可以切换到 byte[] 和 Element.U8
作为RS 元素并写入 0 或 1 而不是 false/true。
关于android - 如何为 RenderScript 输出分配 bool 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25816261/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!