【问题标题】:Nexus 9 Camera2 API - YUV_420_888 vs. getOutputSizes()Nexus 9 Camera2 API - YUV_420_888 与 getOutputSizes()
【发布时间】:2015-05-22 21:14:51
【问题描述】:

我在 Nexus 9 上使用 YUV_420_888 格式实现 Camera2 API。我检查了输出大小并希望使用最大的(8MP,3280 x 2460)大小来保存。但是,它只是显示为静态线,类似于没有信号的旧电视的外观。我想坚持使用 YUV_420_888,因为我的最终目标是保存灰度数据(Y 分量)。

我最初认为这是相机带宽问题,但同样的事情发生在一些小尺寸 (320 x 240) 上。即使我增加了帧持续时间并减小了预览的大小以节省带宽,这些问题都没有消失。其他一些尺寸确实有效(2048 x 1536、1280 x 720),但我没有检查所有尺寸。

我开始认为 getOutputSizes() 可能不一定准确。除了 RAW_SENSOR(JPEG、YUV_420_888、YV12)之外,它给了我所有其他格式相同的结果。有没有人遇到过这种情况或确定了解决方案?

【问题讨论】:

  • 您实际上在做什么来以这种格式保存数据?也许该代码有问题。
  • 好吧,我刚刚写了两个文本文件:一个来自字节直接来自:ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();字节[] 字节 = 新字节[buffer.remaining()];缓冲区.get(字节);还有我直接保存在 C++ 端的 unsigned char 数组。两者匹配相同,所以我相信是来自相机的数据损坏了。
  • 您能否包括在捕获会话中使用的其他输出以及您使用的 Android 版本?这听起来像是 Nexus 9 中的一个潜在错误,因为您到目前为止所描述的应该可以正常工作。
  • @EddyTalvala - 我在 Android 5.0.1 上,构建 LRX22C。我只使用 mImageReader 和实时相机预览。其中大部分来自 Camera2Basic,但由于我不需要 lockFocus 或类似的东西而被精简了。
  • 您是否在捕获高分辨率图像之前运行了一段时间的预览(并且预览看起来不错)?或者您只是在相机打开后立即抓取一个帧?后者是有风险的,因为自动曝光程序还没有收敛到好的值。

标签: android android-camera yuv


【解决方案1】:

解决了这个问题。我没有考虑返回像素的 rowStride。所以我必须在保存之前运行一个 for 循环来提取未填充的数据:

myRowStride = mImage.getPlanes()[0].getRowStride();
int iSkippedBytes = 0;
for (int i = 0; i < mStillSize.getWidth() * mStillSize.getHeight(); i++){
    if (i % mStillSize.getWidth() == 0 && i != 0)
          iSkippedBytes = iSkippedBytes + (myRowStride - mStillSize.getWidth());
    imageBytes[i] = bytes[i + iSkippedBytes];
 }

【讨论】:

  • 另外,您可能还想检查字节步长。它并不总是 1。
  • 对于YUV_420_888,Y分量pixelstride不是一直都是1字节吗?
  • 你是完全正确的,它的 U 和 V 可能有不同的像素步幅。原谅我。
猜你喜欢
  • 1970-01-01
  • 2015-08-11
  • 2017-06-25
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 2017-07-30
  • 2015-06-21
  • 1970-01-01
相关资源
最近更新 更多