从 TangoService_connectOnFrameAvailable 保存帧

2023-12-30

如何通过 TangoService_connectOnFrameAvailable() 保存帧并在我的计算机上正确显示它?作为此参考页 https://developers.google.com/project-tango/apis/c/struct_tango_image_buffer提到,像素以 HAL_PIXEL_FORMAT_YV12 格式存储。在 TangoService_connectOnFrameAvailable 的回调函数中,我像这样保存框架:

static void onColorFrameAvailable(void* context, TangoCameraId id, const TangoImageBuffer* buffer) 
{
  ...
  std::ofstream fp;
  fp.open(imagefile, std::ios::out | std::ios::binary );
  int offset = 0;
  for(int i = 0; i < buffer->height*2 + 1; i++) {
    fp.write((char*)(buffer->data + offset), buffer->width);
    offset += buffer->stride;
  }
  fp.close();
}

然后删除第一行中的元数据并显示我运行的图像:

$ dd if="input.raw" of="new.raw" bs=1 skip=1280
$ vooya new.raw

I was careful to make sure in vooya that the channel order is yvu. The resulting output is: yv12 test image

我在保存图像并显示它时做错了什么?

根据马克·穆林的回复更新:

int offset = buffer->stride; // header offset
// copy Y channel
for(int i = 0; i < buffer->height; i++) {
  fp.write((char*)(buffer->data + offset), buffer->width);
  offset += buffer->stride;
}
// copy V channel
for(int i = 0; i < buffer->height / 2; i++) {
  fp.write((char*)(buffer->data + offset), buffer->width / 2);
  offset += buffer->stride / 2;
}
// copy U channel
for(int i = 0; i < buffer->height / 2; i++) {
  fp.write((char*)(buffer->data + offset), buffer->width / 2);
  offset += buffer->stride / 2;
}

现在显示了下图,但仍然存在一些伪影;我想知道这是来自 Tango 平板电脑相机还是我对原始数据的处理……有什么想法吗?


不能确切地说你做错了什么,而且探戈图像中经常有伪影 - 你的图像是新的,但我经常看到淡蓝色作为一种颜色,其中眩光似乎会烦扰更深的系统,并且当它开始与更深层的系统失去同步时在负载下的深度系统中,您经常会看到看起来像闪亮网格的东西(我认为是红外模式) - 最后,任何使用 openCV 等处理图像的理性尝试都失败了,所以我手写了解码器一些帮助所以这里线程 https://stackoverflow.com/questions/27159916/getting-color-data-in-unity

也就是说,给定 imagebuffer 包含指向 Tango 原始数据的指针,并且从回调中接收到的数据填充各种其他变量(例如高度和步幅),那么此逻辑将创建 RGBA 映射 - 是的,我优化了数学它,所以它有点难看 - 它速度较慢但功能相当的双胞胎被列在第二位。我自己的经验表明,尝试在回调中正确进行解码是一个可怕的想法(我相信 Tango 能够出于纯粹恶意的原因而失去与闪光灯的深度同步),所以我的运行在渲染阶段。

Fast

uchar* pData = TangoData::cameraImageBuffer;
uchar* iData = TangoData::cameraImageBufferRGBA;
int size = (int)(TangoData::imageBufferStride * TangoData::imageBufferHeight);
float invByte = 0.0039215686274509803921568627451;  // ( 1 / 255)

int halfi, uvOffset, halfj, uvOffsetHalfj;
float y_scaled, v_scaled, u_scaled;
int uOffset = size / 4 + size;
int halfstride = TangoData::imageBufferStride / 2;
for (int i = 0; i < TangoData::imageBufferHeight; ++i)
{
    halfi = i / 2;
    uvOffset = halfi * halfstride;
    for (int j = 0; j < TangoData::imageBufferWidth; ++j)
    {
        halfj = j / 2;
        uvOffsetHalfj = uvOffset + halfj;
        y_scaled = pData[i * TangoData::imageBufferStride + j] * invByte;
        v_scaled = 2 * (pData[uvOffsetHalfj + size] * invByte - 0.5f) * Vmax;
        u_scaled = 2 * (pData[uvOffsetHalfj + uOffset] * invByte - 0.5f) * Umax;
        *iData++ = (uchar)((y_scaled + 1.13983f * v_scaled) * 255.0);;
        *iData++ = (uchar)((y_scaled - 0.39465f * u_scaled - 0.58060f * v_scaled) * 255.0);
        *iData++ = (uchar)((y_scaled + 2.03211f * u_scaled) * 255.0);
        *iData++ = 255;
    }
}

可以理解

for (int i = 0; i < TangoData::imageBufferHeight; ++i)
{
    for (int j = 0; j < TangoData::imageBufferWidth; ++j)
    {
        uchar y = pData[i * image->stride + j];
        uchar v = pData[(i / 2) * (TangoData::imageBufferStride / 2) + (j / 2) + size];
        uchar u = pData[(i / 2) * (TangoData::imageBufferStride / 2) + (j / 2) + size + (size / 4)];
        YUV2RGB(y, u, v);
        *iData++ = y;
        *iData++ = u;
        *iData++ = v;
        *iData++ = 255;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 TangoService_connectOnFrameAvailable 保存帧 的相关文章

  • CameraX ImageAnalysis 设置的 TargetResolution 小于 640x480

    我试图通过向 CameraX 的 ImageAnalysis 提供 480x360 图像来提高人脸检测率 然而 以下代码生成 640x480 图像 从而将检测速度降低至 10 fps 如果我提供 480x360 我可以将速率提高到 20 如
  • Unity 的 YUV 着色器?

    我在 Unity 中有一些 适当的 平面的 YUV 纹理 我只想看看它们供开发使用 Unity 他们的着色器语言变体 实际上有一个可用的 YUV 着色器吗 从概念上讲 从 YUV 转换为 RGB 很简单 但有点繁琐 YUV 到 RGB 转换
  • Android 中某些相机分辨率下的不同捕获输出大小

    我正在使用 Android Camera2 API 开发一个自定义相机应用程序 您可以在手机中可用的不同相机和视频分辨率之间切换 它还提供了拍摄 1 1 方形照片的可能性 为了拍摄方形照片 我拍摄了一张正常的 4 3 照片 然后将其裁剪以保
  • 在自动模式下如何获取相机准确的白平衡参数值?

    我有一个Camera http developer android com reference android hardware Camera html白平衡设置为自动的对象 是否可以找到在拍照时应用的真实白平衡参数 似乎没有办法做到这一点
  • 使用 ImageReader 读取 RGB 图像

    我正在尝试使用ImageReader从相机获取 RGB 图像 我在运行开发者预览版的 Nexus 5 上使用 Android 5 0 L 中的 Camera2 API 请注意 我是not询问如何将 YUV 转换为 RGB 我正在尝试直接从I
  • YUV420 到 RGB 转换

    我使用以下公式将 RGB 矩阵转换为 YUV 矩阵 Y 0 257 R 0 504 G 0 098 B 16 Cr V 0 439 R 0 368 G 0 071 B 128 Cb U 0 148 R 0 291 G 0 439 B 128
  • Android Renderscript - 在 Renderscript 中旋转 YUV 数据

    根据我的讨论Camera2 api Imageformat yuv 420 888 旋转图像上的结果 https stackoverflow com questions 44652828 camera2 api imageformat yu
  • 为什么设置 MediaRecorder 时显示错误 IllegalStateException?

    我的代码设置 MediaRecorder 它显示行集质量错误 mMediaRecorder new MediaRecorder Step 1 Unlock and set camera to MediaRecorder mCamera st
  • Android Camera.takePicture() 有时不返回?

    我正在编写一个Android 拍照应用程序 该代码在 onPreviewFrame byte data Cameracamera 中从预览中获取帧后进行一些处理 问题在于 android hardware Camera 的函数 takePi
  • 使用kivy/python访问android手电筒(相机LED闪光灯)

    我不知道如何使用 python 或 kivy 访问 android 上的 led 灯 我尝试安装 python for android 以便能够将 android 模块导入到我的代码中 但不是找不到模块 我按照此处的说明克隆了 python
  • Android 相机 - 将图像保存到 SD 卡中的新文件夹中

    我有一个非常简单的应用程序 目前可以拍照然后保存图像 目前的问题是 由于某种原因 我无法找到图像在手机上的保存位置 我想要做的最终结果是 当拍摄照片时 图像会保存到 SD 卡上创建的新文件夹中 但如果该文件夹尚不存在 则必须创建该文件夹 自
  • OpenGL 使用着色器将 NV12 转换为 RGB24

    我尝试编写一个应用程序来在 OpenGL 中显示 YUV 图像 我使用此代码片段在 C 中成功将 Y UV 转换为 RGB source https blog csdn net subfate article details 4730514
  • Camera.takePicture 返回旋转的 byteArray

    我正在尝试使用制作自定义相机应用程序hardware camera 我已经实现了PictureCallback拍照时会写入指定路径的文件中 这data写入文件的是ByteArray由返回takePicture在相机 API 中 因此 在写入
  • 使用Android Camera API,拍摄照片的方向始终未定义

    我使用相机API 拍摄的照片总是旋转90度 我想旋转它 所以首先我想知道图片的方向 这一点我被卡住了 我总是以两种方式得到未定义的方向 这是代码 Override public void onPictureTaken byte data C
  • 颤动相机显得拉伸

    我一直在玩颤振 到目前为止我很喜欢它 但我在让相机工作时遇到了问题 我按照本页上的说明进行操作https pub dartlang org packages camera https pub dartlang org packages ca
  • setRotation(90) 以肖像模式拍照不适用于三星设备

    根据文档 设置旋转 90 http developer android com reference android hardware Camera Parameters html setRotation 28int 29应旋转捕获的 JPE
  • 使用 HTML5 启用后置摄像头

    我正在开发一个使用 MVC ASP Net 4 HTML5 的项目 默认浏览器是 google chrome v29 0 1547 57 我可以与这些工具交互并拍照 但只能使用前置摄像头 如何启用后置摄像头 平板电脑的特点 三星 Galax
  • 为什么 ARCore 支持的设备有限?

    是什么使得ARCore支持的设备支持ARCore吗 哪些功能使该设备支持 ArCore ARCore 设备和其他不支持的设备有什么区别 发生的情况是不在于有多新手机是 但如果这款手机有一些测试和措施当它被设计和建造时 这是什么意思 您今天的
  • 尝试将相机切换回前面但出现异常

    尝试将相机切换回前面 但出现异常 找不到 问题请检查并帮助 error 01 27 11 49 00 376 E AndroidRuntime 30767 java lang RuntimeException Unable to start
  • Android 拍摄后画质低

    我有一个触发图像捕获的按钮 private void capturePicture if ActivityCompat checkSelfPermission getContext Manifest permission CAMERA Pa

随机推荐