gpt4 book ai didi

android - YUV (NV21) 到移动设备上的 BGR 转换( native 代码)

转载 作者:行者123 更新时间:2023-11-28 07:25:50 38 4
gpt4 key购买 nike

我正在开发一个在 Android 和 IOS 上运行的移动应用程序。它能够实时处理视频流。在 Android 上,我通过 android.hardware.Camera.PreviewCallback.onPreviewFrame 获取相机的预览视频流。我决定使用 NV21 格式,因为所有 Android 设备都应该支持它,而 RGB 不支持(或仅支持 RGB565)。

对于主要用于模式识别的算法,我需要灰度图像和颜色信息。灰度不是问题,但是从 NV21 到 BGR 的颜色转换时间太长。

如前所述,我使用以下方法捕获图像;

在应用程序中,我覆盖了相机的 onPreviewFrame-Handler。这是在 CameraPreviewFrameHandler.java 中完成的:

 @Override
public void onPreviewFrame(byte[] data, Camera camera) {
{
try {
AvCore.getInstance().onFrame(data, _prevWidth, _prevHeight, AvStreamEncoding.NV21);
} catch (NativeException e)
{
e.printStackTrace();
}
}

然后 onFrame-Function 调用一个本地函数,该函数从 Java 对象中获取数据作为本地引用。然后将其转换为 unsigned char* 字节流并调用以下 c++ 函数,该函数使用 OpenCV 将 NV21 转换为 BGR:

void CoreManager::api_onFrame(unsigned char* rImageData, avStreamEncoding_t vImageFormat, int vWidth, int vHeight)
{
// rImageData is a local JNI-reference to the java-byte-array "data" from onPreviewFrame
Mat bgrMat; // Holds the converted image
Mat origImg; // Holds the original image (OpenCV-Wrapping around rImageData)

double ts; // for profiling
switch(vImageFormat)
{
// other formats
case NV21:
origImg = Mat(vHeight + vHeight/2, vWidth, CV_8UC1, rImageData); // fast, only creates header around rImageData
bgrMat = Mat(vHeight, vWidth, CV_8UC3); // Prepare Mat for target image
ts = avUtils::gettime(); // PROFILING START
cvtColor(origImg, bgrMat, CV_YUV2BGRA_NV21);
_onFrameBGRConversion.push_back(avUtils::gettime()-ts); // PROFILING END
break;
}

[...APPLICATION LOGIC...]
}

正如人们可能从代码中的评论中得出的结论,我已经对转换进行了概要分析,结果证明它在我的 Nexus 4 上花费了大约 30 毫秒,对于这样一个“微不足道”的预处理步骤来说,这是 Not Acceptable 时间。 (我的分析方法经过仔细检查,可以正常进行实时测量)

现在,我正拼命寻找从 NV21 到 BGR 的这种颜色转换的更快实现。这是我已经完成的;

  1. 将代码“convertYUV420_NV21toRGB8888”采纳为提供的 C++ in this topic (转化时间的倍数)
  2. 将代码从 1 修改为仅使用整数运算(openCV-Solution 的转换时间加倍)
  3. 浏览了几个其他实现,所有实现都具有相似的转化时间
  4. 检查了 OpenCV-Implementation,他们使用大量位移来获得性能。我想我不能靠自己做得更好

您是否有建议/知道好的实现方式,甚至有完全不同的方法来解决此问题?我不知何故需要从 Android 相机捕获 RGB/BGR 帧,它应该适用于尽可能多的 Android 设备。

感谢您的回复!

最佳答案

你试过libyuv吗?我过去用过它,如果你用 NEON 支持编译它,它使用为 ARM 处理器优化的 asm 代码,你可以从那里开始进一步优化你的特殊情况。

关于android - YUV (NV21) 到移动设备上的 BGR 转换( native 代码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18760037/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com