海康二次开发 C#版 从客户端的出去视频流,并将yv12转换为bgr格式(用于emgucv)。

了解yv12的编码格式,将函数放在回调函数中实现,截获视频流,方便二次开发。


 private  Image  ToBgrImage(IntPtr pBuf, int nSize, int nWidth, int nHeight)         //size608256 wid704 height506
        {
            //分配内存通道并设置格式(这里必须使用bitmap进行分配)
            Bitmap bmp = new Bitmap(nWidth, nHeight, PixelFormat.Format24bppRgb);
            Rectangle rect = new Rectangle(0, 0, nWidth, nHeight);
            BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            //对内存中的数据尽心分配
            unsafe
            {
                //或者分配内存的首地址  并进行类型转换
                byte* ptr = (byte*)(bmpdata.Scan0);

                for (int i = 0; i < nHeight; i++)                   //按行存储
                {
                    for (int j = 0; j < nWidth; j++)
                    {
                        //求取pbuf中的yuv分量,并转换为rgb格式,最后将rgb进行赋值给内存区域

                        //1 获取huv三个分量         /!!!!这个地方要注意,int相除默认是四舍五入,一定要进行更改求floor
                        byte y = ((byte*)pBuf)[i * nWidth + j];
                        byte v = ((byte*)pBuf)[nWidth * nHeight + (byte)Math.Floor(((double)i * nWidth + j) / 4)];
                        byte u = ((byte*)pBuf)[nWidth * nHeight + nWidth * nHeight / 4 + (byte)Math.Floor(((double)i * nWidth + j) / 4)];

                        //2 获取double精度的rgb
                        double r = 1.1640625 * (y - 16) + 1.59765625 * (v - 128) + 0.5;
                        double g = 1.1640625 * (y - 16) - 0.390625 * (u - 128) - 0.8125 * (v - 128) + 0.5;
                        double b = 1.1640625 * (y - 16) + 2.015625 * (u - 128) + 0.5;
                        //3 将数值写入到内存中的数组
                        ptr[0] = (byte)(b > 0 ? b > 255 ? 255 : b : 0);
                        ptr[1] = (byte)(g > 0 ? g > 255 ? 255 : g : 0);
                        ptr[2] = (byte)(r > 0 ? r > 255 ? 255 : r : 0);

                       //ptr[0] = 0;
                       //ptr[1] = 0;
                        //ptr[2] = 0;
                        ptr += 3;
                    }
                    ptr += bmpdata.Stride - bmpdata.Width * 3;                              //为什么会产生偏色?四舍五入的原因
                }
                bmp.UnlockBits(bmpdata);
                Image imageTemp = new Image(bmp);
                imgBox3.Image = imageTemp;
                return imageTemp;
            }
        }       


你可能感兴趣的:(C#,海康二次开发)