从TangoService_connectOnFrameAvailable保存框架 [英] Save frame from TangoService_connectOnFrameAvailable

查看:335
本文介绍了从TangoService_connectOnFrameAvailable保存框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何节省通过TangoService_connectOnFrameAvailable(框架),并正确显示在我的电脑上?作为 提到此参考页中,像素被存储在HAL_PIXEL_FORMAT_YV12格式。在TangoService_connectOnFrameAvailable我的回调函数,我保存框架是这样的:

How can I save a frame via TangoService_connectOnFrameAvailable() and display it correctly on my computer? As this reference page mentions, the pixels are stored in the HAL_PIXEL_FORMAT_YV12 format. In my callback function for TangoService_connectOnFrameAvailable, I save the frame like this:

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();
}

然后除掉的元数据的第一行中和,以显示我运行图像:

Then to get rid of the meta data in the first row and to display the image I run:

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

我很小心,以确保在vooya信道顺序是YVU。所得到的输出是:

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

我在做什么错在保存图像和显示呢?

What am I doing wrong in saving the image and displaying it?

每马克 - 穆林的回应更新:

UPDATE per Mark Mullin's response:

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;
}

这现在显示下面的图片,但仍有一些文物;不知从探戈平板电脑相机或我的原始数据的处理...什么想法?

This now shows the picture below, but there are still some artifacts; I wonder if that's from the Tango tablet camera or my processing of the raw data... any thoughts?

推荐答案

不能说你在做什么错误和探戈的图像往往在他们的神器 - 你是新的,但我经常看到淡蓝色的颜色刺眼的地方似乎是恼人的更深层次的制度,因为它开始松动同步与负载下的深度系统,你会经常看到什么看起来像一个闪亮的网格(其IR模式,我认为) - 最后,任何理性试图处理与OpenCV的失败等形象,所以我写了手去codeR从的 SO线程这里

Can't say exactly what you're doing wrong AND tango images often have artifacts in them - yours are new, but I often see baby blue as a color where glare seems to be annoying deeper systems, and as it begins to loose sync with the depth system under load, you'll often see what looks like a shiny grid (its the IR pattern, I think) - At the end, any rational attempt to handle the image with openCV etc failed, so I hand wrote the decoder with some help from SO thread here

也就是说,鉴于ImageBuffer的包含一个指向从探戈的原始数据,以及其他各种变量,如身高和步幅是从回调接收到的数据填充,那么这个逻辑将创建一个RGBA地图 - 是啊,我的优化数学的,所以这是一个有点难看 - 这是慢,但功能相当的双胞胎被列第二。我自己的经验说,它是一个可怕的想法,试图在回调(我相信探戈能够失去闪光灯深度为纯粹恶意的原因同步)做到这一点去code正确的,所以我的运行在渲染阶段。

That said, given imagebuffer contains a pointer to the raw data from Tango, and various other variables like height and stride are filled in from the data received in the callback, then this logic will create an RGBA map - yeah, I optimized the math in it, so it's a little ugly - it's slower but functionally equivalent twin is listed second. My own experience says its a horrible idea to try and do this decode right in the callback (I believe Tango is capable of loosing sync with the flash for depth for purely spiteful reasons), so mine runs at the render stage.

快速

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;
    }
}

这篇关于从TangoService_connectOnFrameAvailable保存框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆