【发布时间】:2016-03-06 12:14:57
【问题描述】:
我正在尝试从相机预览中捕获图像并在其上进行一些绘图。问题是,我只有大约 3-4 fps 的绘图,一半的帧处理时间是从相机预览接收和解码 NV21 图像并转换为位图。我有一个代码来完成这个任务,我在另一个堆栈问题上找到了它。它似乎并不快,但我不知道如何优化它。在三星 Note 3 上大约需要 100-150 毫秒,图像尺寸为 1920x1080。我怎样才能让它更快地工作?
代码:
public Bitmap curFrameImage(byte[] data, Camera camera)
{
Camera.Parameters parameters = camera.getParameters();
int imageFormat = parameters.getPreviewFormat();
if (imageFormat == ImageFormat.NV21)
{
YuvImage img = new YuvImage(data, ImageFormat.NV21, prevSizeW, prevSizeH, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
img.compressToJpeg(new android.graphics.Rect(0, 0, img.getWidth(), img.getHeight()), 50, out);
byte[] imageBytes = out.toByteArray();
return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
}
else
{
Log.i(TAG, "Preview image not NV21");
return null;
}
}
图像的最终格式必须是位图,所以我可以对其进行处理。我尝试将 Camera.Parameters.setPreviewFormat 设置为 RGB_565,但无法将相机参数分配给相机,我还读到 NV21 是唯一可用的格式。我不确定是否可以在这些格式更改中找到解决方案。
提前谢谢你。
【问题讨论】:
-
最快的方法是使用 RenderScript 内在函数,但问题是为什么每秒需要这么多位图?绘制这些位图或存储它们将成为您流程的下一个瓶颈,速度为 10 FPS 或更低
-
谢谢。我的任务是在相机预览中围绕文本字段绘制矩形,因此当相机移动时,我希望保持文本字段周围的边界也移动,并在新找到的文本字段周围查找和绘制矩形(因此此处无法进行跟踪) .这是我第一次做这样的事情,比如在相机预览上实时绘图,所以也许你有什么建议或意见,也许我在这里做错了什么?
-
考虑通过 OpenGL 渲染你的矩形;您无法显示 SurfaceTexture 来渲染相机预览,因为您的矩形将显示有一些延迟(识别和跟踪算法)。最好使用着色器手动渲染 YUV 预览帧,与您的矩形完美同步。也许您的识别和跟踪算法也可能被调整为依赖 YUV 数据而不是 RGB?
-
“你不能显示 SurfaceTexture 来渲染相机预览”——我不是。我只是在 onPreviewFrame 函数中从这个函数接收图像,在其他 SurfaceView 上的画布上进行处理和绘制线条(通过处理找到它们的坐标),就像这样
canvas.drawLine(...(如果我正确理解你的陈述)。实际上,我认为调整算法以支持 YUV 图像的想法非常好,但我仍然对优化这种转换感兴趣,因为这看起来很糟糕。谢谢你,很抱歉花了太长时间回复,我很忙。 -
在 GoogleSource 上查看 example:使用 RenderScript 内部函数进行一些图像处理和 YUV 到 RGB 转换来显示它。
标签: java android bitmap camera yuv