C#.NET中的快速数据处理:RRGGBB到位图/C#视频/图像处理

C#.NET中的快速数据处理:RRGGBB到位图/C#视频/图像处理,c#,performance,video,bitmap,x86,C#,Performance,Video,Bitmap,X86,我从一个摄像头获取图像数据,它是一个非托管dll中的UShort数组 我已经设法以相当好的速度将数据输入到管理区 // cpp .NET static void imageCallback(unsigned short * rawData, unsigned int length) { array<unsigned short>^ imageData = gcnew array<unsigned short>(length); unsigned int

我从一个摄像头获取图像数据,它是一个非托管dll中的UShort数组

我已经设法以相当好的速度将数据输入到管理区

// cpp .NET
static void imageCallback(unsigned short * rawData, unsigned int length) {

    array<unsigned short>^ imageData = gcnew array<unsigned short>(length);

    unsigned int headLength = 512; // header length in shorts

    pin_ptr<unsigned short> imageDataStart = &imageData[0];
    memcpy(imageDataStart, rawData + headLength, length);

    callBackDelegate(imageData);
}
//cpp.NET
静态void imageCallback(无符号短*原始数据,无符号整数长度){
数组^imageData=gcnew数组(长度);
unsigned int headLength=512;//短标题长度
pin_ptr imageDataStart=&imageData[0];
memcpy(imageDataStart,rawData+头长,长度);
callBackDelegate(imageData);
}
对于每个颜色通道,数据按“RGBRGBRGB…”的顺序排列

然后,托管阵列通过委托发送到C#。然后,我必须将原始数据转换成(8位值)位图,方法如下:

    public static Bitmap RGBDataToBitmap(ushort[] data, int Width, int Height, int bitDepth)
    {
        Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);

        var rawdata = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadWrite, bmp.PixelFormat);
        var pixelSize = rawdata.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3; // only works with 32 or 24 pixel-size bitmap!
        var padding = rawdata.Stride - (rawdata.Width * pixelSize);
        var bytes = new byte[rawdata.Height * rawdata.Stride];

        var index = 0;
        var pixel = 0;

        // scale to 8 bits
        var scalar = Math.Pow(2, -(bitDepth - 8));

        for (var y = 0; y < Height; y++)
        {
            for (var x = 0; x < Width; x++)
            {

                int Rlevel = (int)Math.Round(data[pixel + 0] * scalar);
                int Glevel = (int)Math.Round(data[pixel + 1] * scalar);
                int Blevel = (int)Math.Round(data[pixel + 2] * scalar);

                pixel += 3;

                bytes[index + 3] = 255; // A component 
                bytes[index + 2] = Convert.ToByte(Blevel); // B component
                bytes[index + 1] = Convert.ToByte(Glevel); // G component
                bytes[index + 0] = Convert.ToByte(Rlevel); // R component

                index += pixelSize;
            }

            index += padding;
        }

        // copy back the bytes from array to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(bytes, 0, rawdata.Scan0, bytes.Length);

        bmp.UnlockBits(rawdata);

        return bmp;
    }
public静态位图RGBDataToBitmap(ushort[]数据,int-Width,int-Height,int-bitDepth)
{
位图bmp=新位图(宽度、高度、像素格式.Format32bppArgb);
var rawdata=bmp.LockBits(新矩形(Point.Empty,bmp.Size),ImageLockMode.ReadWrite,bmp.PixelFormat);
var pixelSize=rawdata.PixelFormat==PixelFormat.Format32bppArgb?4:3;//仅适用于32或24像素大小的位图!
var padding=rawdata.Stride-(rawdata.Width*pixelSize);
var bytes=新字节[rawdata.Height*rawdata.Stride];
var指数=0;
var像素=0;
//缩放到8位
var标量=数学功率(2,-(比特深度-8));
对于(变量y=0;y
如果我对该操作计时(从原始数据到位图),则需要约0.5秒。帧以每秒约12次的速度进入,因此速度太慢

有人看到我用C#加快这个操作的方法了吗?或者有人对另一种方法有任何指导吗

目标是用C#制作一个实时视频图像

谢谢

编辑:

根据以下建议,如果我将for循环更改为:

        // scale to 8 bits
        var bitminus8 = bitDepth - 8;
        var scalar = Math.Pow(2, -(bitminus8));

        Parallel.For(0, Height, y =>
        {
            var index = y * Width;

            for (var x = 0; x < Width; x++)
            {
                var idx = index + x;

                byte Rlevel = (byte)(data[idx * 3 + 0] >> bitminus8);
                byte Glevel = (byte)(data[idx * 3 + 1] >> bitminus8);
                byte Blevel = (byte)(data[idx * 3 + 2] >> bitminus8);

                bytes[idx * 4 + 3] = 255; // A component 
                bytes[idx * 4 + 2] = Blevel; // B component
                bytes[idx * 4 + 1] = Glevel; // G component
                bytes[idx * 4 + 0] = Rlevel; // R component

            }
        });
//缩放到8位
var bitmus8=位深度-8;
var标量=数学功率(2,-(8位));
平行。对于(0,高度,y=>
{
var指数=y*宽度;
对于(变量x=0;x>位8);
字节Glevel=(字节)(数据[idx*3+1]>>位8);
字节Blevel=(字节)(数据[idx*3+2]>>位8);
字节[idx*4+3]=255;//一个组件
字节[idx*4+2]=Blevel;//B组件
字节[idx*4+1]=Glevel;//G组件
字节[idx*4+0]=Rlevel;//R组件
}
});

从0.5秒到0.04秒。字节转换有点不错,这带来了很大的不同被称为x*y倍?还有为什么
如果(Xlevel<0){Xlevel=0;}
<代码>X级别
不能<0查找
不安全
用于C#。。。结果几乎相同。。。猜猜看什么更快。。无论如何,创建位图时不会得到12 Hz的频率。。。如果你想展示这一点,你应该直接使用GPU和这个缓冲区,所以现在你可以每秒处理25帧,对吗?有多少逻辑/物理内核?你想快点吗?如果您不想让程序占用太多CPU时间,那么使用GPU可能是一个不错的选择。