C# 将Format16bppGrayScale位图转换为BitmapImage

C# 将Format16bppGrayScale位图转换为BitmapImage,c#,.net,bitmap,bitmapimage,realsense,C#,.net,Bitmap,Bitmapimage,Realsense,我正在使用Intel RealSense SDK开发C#应用程序。 我使用了这个能够在颜色框架中跟踪人的示例: 该示例可以显示一个人身体的X,Y坐标,但不能显示他的距离,除非它看到一张脸(Z坐标),而不是这个,我还想记录和显示屏幕上的人的深度数据(灰度图像)。 示例程序在能够在屏幕上显示图像之前执行的一个步骤是将“英特尔RealSense”中的图像数据转换为格式为32bpparGB的位图,然后再将其转换为位图图像 以下是将ImageData(颜色)转换为Format32bppArgb位图的代码,

我正在使用Intel RealSense SDK开发C#应用程序。 我使用了这个能够在颜色框架中跟踪人的示例:

该示例可以显示一个人身体的X,Y坐标,但不能显示他的距离,除非它看到一张脸(Z坐标),而不是这个,我还想记录和显示屏幕上的人的深度数据(灰度图像)。 示例程序在能够在屏幕上显示图像之前执行的一个步骤是将“英特尔RealSense”中的图像数据转换为格式为32bpparGB的位图,然后再将其转换为位图图像

以下是将ImageData(颜色)转换为Format32bppArgb位图的代码,用于RealSense(示例)中的ImageData:

我创建了一个单独的方法来将(深度)图像数据转换为Format16bppGrayScale位图,在该方法中,我预先将格式设置为PixelFormat.PIXEL\u format\u depth\u RAW,我将其用于深度数据

public Bitmap ToDepthBitmap(Int32 index, Int32 width, Int32 height)
{
    Bitmap bitmap = null;
    format = PixelFormat.PIXEL_FORMAT_DEPTH;
    switch (format)
    {
        case PixelFormat.PIXEL_FORMAT_RGB32:
            bitmap = new Bitmap(width, height, pitches[index], System.Drawing.Imaging.PixelFormat.Format32bppArgb, planes[0]);
            break;
        case PixelFormat.PIXEL_FORMAT_RGB24:
            bitmap = new Bitmap(width, height, pitches[index], System.Drawing.Imaging.PixelFormat.Format24bppRgb, planes[0]);
            break;
        case PixelFormat.PIXEL_FORMAT_DEPTH:
        case PixelFormat.PIXEL_FORMAT_DEPTH_RAW:
            bitmap = new Bitmap(width, height, pitches[index], System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, planes[index]);
            break;
        default:
            return null;
    }
    return bitmap;
}
下面是将Format32bppArgb位图转换为BitmapImage并在屏幕上显示的代码(来自示例):

我再次添加了一个单独的方法,尝试对DepthData流执行相同的步骤(将16bppgrayscale位图格式化为BitmapImage):

private void RenderDepth(Bitmap bitmap, MyTrackedPerson myTrackedPerson)
{
    Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate ()
    {
        BitmapImage bitmapImage = ConvertDepthBitmap(bitmap);
        if (bitmapImage != null)
        {
            imgStream.Source = bitmapImage;
        }
    }));
}

private BitmapImage ConvertDepthBitmap(Bitmap bitmap)
{
    BitmapImage bitmapImage = null;

    if (bitmap != null)
    {
        MemoryStream memoryStream = new MemoryStream();

        var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        var bitmapCopy = (Bitmap)bitmap.Clone();
        var bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

        var numberOfBytes = bitmapData.Stride * bitmap.Height;
        var bitmapBytes = new short[bitmap.Width * bitmap.Height];

        var k = 0;

        for (int i = 0; i < bitmap.Width; i++)
        {
            for (int j = 0; j < bitmap.Height; j++)
            {
                bitmapBytes[k] = (short)bitmapCopy.GetPixel(i, j).ToArgb();
                k++;
            }
        }

        var ptr = bitmapData.Scan0;
        Marshal.Copy(bitmapBytes, 0, ptr, bitmapBytes.Length);

        bitmap.UnlockBits(bitmapData);

        bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
        memoryStream.Position = 0;
        bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = memoryStream;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
        bitmapImage.Freeze();
    }

    return bitmapImage;
}

有人能指出我是否遗漏了什么吗?我做得不对吗?

GetPixel
速度非常慢。最好不要用它。如果要快速完成此操作,必须手动处理原始数据。或者将任何第三方库用于开箱即用的解决方案,例如OpenCV.16bppGrayScale在许多方面都很麻烦,例如,没有任何像样的颜色映射。不要使用它。
GetPixel
非常慢。最好不要用它。如果要快速完成此操作,必须手动处理原始数据。或者将任何第三方库用于开箱即用的解决方案,例如OpenCV.16bppGrayScale在许多方面都很麻烦,例如,没有任何像样的颜色映射。不要用它。
private void Render(Bitmap bitmap, MyTrackedPerson myTrackedPerson)
{
    Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate ()
    {
        BitmapImage bitmapImage = ConvertBitmap(bitmap);
        if (bitmapImage != null)
        {
            imgStream.Source = bitmapImage;
        }
    }));
}

private BitmapImage ConvertBitmap(Bitmap bitmap)
{
    BitmapImage bitmapImage = null;

    if (bitmap != null)
    {
        MemoryStream memoryStream = new MemoryStream();
        bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
        memoryStream.Position = 0;
        bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = memoryStream;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
        bitmapImage.Freeze();
    }

    return bitmapImage;
}
private void RenderDepth(Bitmap bitmap, MyTrackedPerson myTrackedPerson)
{
    Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate ()
    {
        BitmapImage bitmapImage = ConvertDepthBitmap(bitmap);
        if (bitmapImage != null)
        {
            imgStream.Source = bitmapImage;
        }
    }));
}

private BitmapImage ConvertDepthBitmap(Bitmap bitmap)
{
    BitmapImage bitmapImage = null;

    if (bitmap != null)
    {
        MemoryStream memoryStream = new MemoryStream();

        var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        var bitmapCopy = (Bitmap)bitmap.Clone();
        var bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

        var numberOfBytes = bitmapData.Stride * bitmap.Height;
        var bitmapBytes = new short[bitmap.Width * bitmap.Height];

        var k = 0;

        for (int i = 0; i < bitmap.Width; i++)
        {
            for (int j = 0; j < bitmap.Height; j++)
            {
                bitmapBytes[k] = (short)bitmapCopy.GetPixel(i, j).ToArgb();
                k++;
            }
        }

        var ptr = bitmapData.Scan0;
        Marshal.Copy(bitmapBytes, 0, ptr, bitmapBytes.Length);

        bitmap.UnlockBits(bitmapData);

        bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
        memoryStream.Position = 0;
        bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = memoryStream;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
        bitmapImage.Freeze();
    }

    return bitmapImage;
}
bitmapBytes[k] = (short)bitmapCopy.GetPixel(i, j).ToArgb();