Создано изображение UYVY поверх directshow и оно повреждено, и я не знаю, почему - PullRequest
0 голосов
/ 09 сентября 2011

У меня есть буфер данных UYVY с камеры, и я использую фильтр GSSF Directshow.net, чтобы протолкнуть буфер через график.

График на данный момент составляет

GSSF -> YUV Transform -> AVI Splitter -> Video Renderer

График правильно вычисляет цвет и отображает его правильно, но на изображении нет полос, которых не должно быть, и я не уверен, откуда они берутся. Мне больно смотреть на изображение.

enter image description here

Эта функция берет буфер UYVY (основной байт) и копирует его в массив целых чисел

        unsafe public void ImageFromPixels__()
    {
        byte[] x = mainbyte;
        long fff = 720 * 1280;
        mainptr = new IntPtr(fff);
        for (int p = 0; p < 720 * 1280; p++)
        {
            U = (x[p * 4 + 0]);

            Y = (x[p * 4 + 1]);
            V = (x[p * 4 + 2]);
            Y2 = (x[p * 4 + 3]);

           // int one = V << 16 | Y << 8 | U;
           // int two = V << 16 | Y2 << 8 | U;
            int one = Y2 << 24 | V << 16 | Y << 8 | U;
           // mainint[p * 2 + 0] = one;
           // mainint[p * 2 + 1] = two;
            mainint[p] = one;

        }

        m_FPS = UNIT / 20;
        m_b = 211;
        m_g = 197;
    }

Эта функция берет тот же массив целых чисел и упаковывает его в указатель потока GSSF

        override unsafe public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead)
    {
        int hr = 0;

        if (iFrameNumber>-1)
        {
            if (iFrameNumber < MAXFRAMES)
            {
                ImageFromPixels_(20, mainbyte);

                m_g += 3;
                m_b += 7;
                int* bp = (int*)ip.ToPointer();
                Random k = new Random();

                StreamReader s = new StreamReader("jpegFile.txt");
                for (int f = 0; f < HEIGHT; f++)
                {
                    for (int x = 0; x < (WIDTH); x += 1)
                    {
                        *(bp + (f * WIDTH) + x) = mainint[f * 1280 + x];
                    }
                }
            }
            else
            {
                hr = 1; // End of stream
            }
        }

        iRead = iSize;

        return hr;
    }

Это устанавливает сжатие растрового изображения для выходного контакта GSSF Я думаю, что я могу делать что-то не так, но это выглядит правильно.

        override public void SetMediaType(IGenericSampleConfig psc)
    {
        BitmapInfoHeader bmi = new BitmapInfoHeader();

        // Build a BitmapInfo struct using the parms from the file
        bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
        bmi.Width = WIDTH;
        bmi.Height = HEIGHT * -1;
        bmi.Planes = 1;
        bmi.BitCount = BPP;
        bmi.Compression = 0x59565955; //UYVY
        bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height;
        bmi.XPelsPerMeter = 0;
        bmi.YPelsPerMeter = 0;
        bmi.ClrUsed = 0;
        bmi.ClrImportant = 0;

        int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS);
        DsError.ThrowExceptionForHR(hr);
    }

UPDATE изменил abit

        override unsafe public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead)
    {
        int hr = 0;

        if (iFrameNumber>-1)
        {
            if (iFrameNumber < MAXFRAMES)
            {
                ImageFromPixels_(20, mainbyte);

                m_g += 3;
                m_b += 7;
                int* bp = (int*)ip.ToPointer();
                Random k = new Random();
                StreamReader s = new StreamReader("jpegFile.txt");
                for (int f = 0; f < 720; f++)
                {
                    for (int x = 0; x < (1280); x += 1)
                    {
                        *(bp + (f * 1280) + x) = mainint[f * 1280 + x];
                    }
                }
            }
            else
            {
                hr = 1; // End of stream
            }
        }

// переопределить public void SetMediaType (IGenericSampleConfig psc) { BitmapInfoHeader bmi = new BitmapInfoHeader ();

        // Build a BitmapInfo struct using the parms from the file
        bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
        bmi.Width = WIDTH;
        bmi.Height = HEIGHT * -1;
        bmi.Planes = 1;
        bmi.BitCount = BPP;
        bmi.Compression = 0x59565955;
        bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height;
        bmi.XPelsPerMeter = 0;
        bmi.YPelsPerMeter = 0;
        bmi.ClrUsed = 0;
        bmi.ClrImportant = 0;

        int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS);
        DsError.ThrowExceptionForHR(hr);
    }

//

        unsafe public void ImageFromPixels_(long FPS, byte[] x)
    {

        long fff = 720 * 1280 * 3;
        mainptr = new IntPtr(fff);
        for (int p = 0; p < 720 * 640; p++)
        {
            U = (x[ p * 4 + 0]);

            Y = (x[p * 4 + 1]);
            V = (x[p * 4 + 2]);
            Y2 = (x[p * 4 + 3]);

            int one = Y2 << 24 | V << 16 | Y << 8 | U;
            //int one = V << 16 | Y << 8 | U;
            //int two = V << 16 | Y2 << 8 | U;
            //mainint[p * 2 + 0] = one;
            //mainint[p * 2 + 1] = two;
            mainint[p] = one;

        }

        m_FPS = UNIT / FPS;
        m_b = 211;
        m_g = 197;
    }

enter image description here

если я изменю другие числа в GetImage, чтобы изменить высоту видео, или если я изменю его внутри ImagePixel, тогда я просто получу черные экраны: |

Ответы [ 2 ]

1 голос
/ 09 сентября 2011

Указатель по математике отстой. Изменил мой код с

for (int f = 0; f < 720; f++)
{
    for (int x = 0; x < (1280); x += 1)
    {
        *(bp + (f * 1280) + x) = mainbyte[f * 1280 + x];
    }
}

до

Marshal.Copy(mainbyte, 0, ip, 1280*720);

и изменил BPP с 32 на 16, и теперь он работает без помех.

<_ <</p>

0 голосов
/ 09 сентября 2011

Как получается, что ваш цикл до (720 * 1280), то есть одна итерация для каждого пикселя изображения, но внутри цикла вы выполняете Y и Y2. Это не выглядит правильно.

...