如何使逐像素图像处理更快?
How to make pixel by pixel PImage manipulation faster?
我正在制作一个 android 应用程序,其中有一个简单的相机 UI 以及一个过滤器列表来处理相机点击的图片。
我在处理 IDE.
中使用处理库 (https://processing.org/) in Java along with the Ketai library (http://ketai.org/)
以下是我的程序主要运行的方式:
--- 我有一个相机对象和一个空图像对象。图像对象与相机的分辨率相同。
--- 从相机中读取也 returns 图像对象。让我们将相机返回的图像称为 cameraImage,将空图像称为 dummyImage。
--- 在每一帧,我使用 cameraImage 的像素数组从相机读取,我将每个像素单独复制到相应坐标位置的 dummyImage。
--- 在从 cameraImage 复制到 dummyImage 的这一点上,我根据用户选择的选项操作像素。
--- 我使用每个像素的红色、绿色和蓝色值,同时使用位移位复制它(以获得最大效率),然后对其进行操作。
--- 复制到 dummyImage 完成后,我将 dummyImage 作为普通图像显示到屏幕上。
现在的问题是,当我直接显示 cameraImage 时,我很容易就能达到 50 到 60 fps 左右。但是当我在复制后显示 dummyImage 时,我得到大约 1.5 fps。
以下代码演示了我如何从 cameraImage 复制到 dummyImage。它没有任何过滤器,但会花费与任何过滤器一样多的时间。
cameraImage.read();
cameraImage.loadPixels();
dummyImage.loadPixels();
for (int x = 0; x < cameraImage.width; x++){
for (int y = 0; y < cameraImage.height; y++){
int index = x + (y * cameraImage.width);
color currentPixel = cameraImage.pixels[index];
float r = currentPixel >> 16 & 0xFF;
float g = currentPixel >> 8 & 0xFF;
float b = currentPixel & 0xFF;
dummyImage[index] = color(r, g, b)
}
}
dummyImage.updatePixels();
image(dummyImage);
我想知道如何将帧数提高到每秒至少 20 帧。请评论以获取更多信息,我会尽快回复。
一些可能的优化:
将 = color(r, g, b)
替换为= 0xff000000 | ((int) (r) << 16 | (int) (g) << 8 | (int) (b))
。
你不能在并行处理中光栅化图形,但你可以并行read/write到pixels[]
数组(然后updatePixels()
),所以使用thread()
将像素迭代拆分到多个 CPU 线程。
而不是调用 image(dummyImage)
,这涉及第二次遍历像素以将它们复制到 PApplet
,直接在循环内写入 PApplet(删除所有引用到 dummyImage
并改用 pixels[index] = ...
)。
由于 pixel-by-pixel 计算是 令人尴尬的并行 ,您甚至可以考虑编写一个 glsl 着色器(有很多处理示例)或使用Aparapi,将 Java 代码转换为 GPU-ready OpenCL(我已经成功地将其与 Processing 一起使用)。
我正在制作一个 android 应用程序,其中有一个简单的相机 UI 以及一个过滤器列表来处理相机点击的图片。 我在处理 IDE.
中使用处理库 (https://processing.org/) in Java along with the Ketai library (http://ketai.org/)以下是我的程序主要运行的方式:
--- 我有一个相机对象和一个空图像对象。图像对象与相机的分辨率相同。
--- 从相机中读取也 returns 图像对象。让我们将相机返回的图像称为 cameraImage,将空图像称为 dummyImage。
--- 在每一帧,我使用 cameraImage 的像素数组从相机读取,我将每个像素单独复制到相应坐标位置的 dummyImage。
--- 在从 cameraImage 复制到 dummyImage 的这一点上,我根据用户选择的选项操作像素。
--- 我使用每个像素的红色、绿色和蓝色值,同时使用位移位复制它(以获得最大效率),然后对其进行操作。
--- 复制到 dummyImage 完成后,我将 dummyImage 作为普通图像显示到屏幕上。
现在的问题是,当我直接显示 cameraImage 时,我很容易就能达到 50 到 60 fps 左右。但是当我在复制后显示 dummyImage 时,我得到大约 1.5 fps。
以下代码演示了我如何从 cameraImage 复制到 dummyImage。它没有任何过滤器,但会花费与任何过滤器一样多的时间。
cameraImage.read();
cameraImage.loadPixels();
dummyImage.loadPixels();
for (int x = 0; x < cameraImage.width; x++){
for (int y = 0; y < cameraImage.height; y++){
int index = x + (y * cameraImage.width);
color currentPixel = cameraImage.pixels[index];
float r = currentPixel >> 16 & 0xFF;
float g = currentPixel >> 8 & 0xFF;
float b = currentPixel & 0xFF;
dummyImage[index] = color(r, g, b)
}
}
dummyImage.updatePixels();
image(dummyImage);
我想知道如何将帧数提高到每秒至少 20 帧。请评论以获取更多信息,我会尽快回复。
一些可能的优化:
将
= color(r, g, b)
替换为= 0xff000000 | ((int) (r) << 16 | (int) (g) << 8 | (int) (b))
。你不能在并行处理中光栅化图形,但你可以并行read/write到
pixels[]
数组(然后updatePixels()
),所以使用thread()
将像素迭代拆分到多个 CPU 线程。而不是调用
image(dummyImage)
,这涉及第二次遍历像素以将它们复制到PApplet
,直接在循环内写入 PApplet(删除所有引用到dummyImage
并改用pixels[index] = ...
)。由于 pixel-by-pixel 计算是 令人尴尬的并行 ,您甚至可以考虑编写一个 glsl 着色器(有很多处理示例)或使用Aparapi,将 Java 代码转换为 GPU-ready OpenCL(我已经成功地将其与 Processing 一起使用)。