C # OpenCV VideoWriter сохраняет в неожиданных цветах

#c# #wpf #emgucv #writeablebitmap #realsense

#c# #wpf #emgucv #доступная для записи bitmap #realsense

Вопрос:

Я использую камеру Intel Realsense RGB для отображения прямой трансляции в окне WPF, а также сохранения потока в файл. То, что я показываю в окне, имеет правильные цвета, но когда я сохраняю его, цвета видео не отображаются (более фиолетовые). Пожалуйста, смотрите скриншот:https://ibb.co/txy9Sgd

Я использую EmguCV video Writer для сохранения видео. Я не очень разбираюсь в форматах. Я предполагаю, что я делаю что-то не так с форматом Format24bppRgb?

 private Pipeline pipeline = new Pipeline(); // Create and config the pipeline to strem color and depth frames.
private CancellationTokenSource tokenSource;
private VideoWriter writer = null;

public StartTests()
{
    InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    tokenSource = new CancellationTokenSource();
    int fcc = VideoWriter.Fourcc('M', 'P', '4', 'V'); //'M', 'J', 'P', 'G'
    float fps = 15F;
    writer = new VideoWriter("testttt.mp4", fcc, fps, new System.Drawing.Size(640, 480), true);

    Config cfg = new Config();
    cfg.EnableStream(Stream.Color, 640, 480, format: Format.Rgb8);
    PipelineProfile pp = pipeline.Start(cfg);
    StartRenderFrames(pp);
}

private void StartRenderFrames(PipelineProfile pp)
{
    // Allocate bitmaps for rendring. Since the sample aligns the depth frames to the color frames, both of the images will have the color resolution
    using (VideoStreamProfile p = pp.GetStream(Stream.Color) as VideoStreamProfile)
    {
        imgColor.Source = new WriteableBitmap(p.Width, p.Height, 96d, 96d, PixelFormats.Rgb24, null);
    }
    Action<VideoFrame> updateColor = UpdateImage(imgColor);

    Task.Factory.StartNew(() =>
    {
        while (!tokenSource.Token.IsCancellationRequested)
        {
            using (FrameSet frames = pipeline.WaitForFrames()) // Wait for the next available FrameSet
            {
                VideoFrame colorFrame = frames.ColorFrame.DisposeWith(frames);

                // Save frames to file here...
                System.Drawing.Bitmap ColorImg = new System.Drawing.Bitmap(colorFrame.Width, colorFrame.Height, colorFrame.Stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, colorFrame.Data);
                Image<Bgr, Byte> imageCV = new Image<Bgr, byte>(ColorImg); //Image Class from Emgu.CV
                Mat matFrame = imageCV.Mat;
                writer.Write(matFrame);

                // Render to WPF window here...
                Dispatcher.Invoke(DispatcherPriority.Render, updateColor, colorFrame);
            }
        }
    }, tokenSource.Token);
}

static Action<VideoFrame> UpdateImage(Image img)
{
    WriteableBitmap wbmp = img.Source as WriteableBitmap;
    return new Action<VideoFrame>(frame =>
    {
        using (frame)
        {
            var rect = new Int32Rect(0, 0, frame.Width, frame.Height);
            wbmp.WritePixels(rect, frame.Data, frame.Stride * frame.Height, frame.Stride);
        }
    });
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    tokenSource.Cancel();
    tokenSource.Dispose();
    pipeline.Stop();
    writer.Dispose();
    tokenSource = new CancellationTokenSource();
}
  

Я хочу видеть одинаковые цвета в сохраненном файле .mp4, но я вижу странные цвета.

Примечание — Мой код основан на этом примере: https://github.com/IntelRealSense/librealsense/blob/master/wrappers/csharp/cs-tutorial-2-capture/Window.xaml.cs

Ответ №1:

OpenCV использует цветовой формат BGR, поэтому, если вы измените формат потока RealSense на Format.Bgra8 , а WriteableBitmap формат на PixelFormats.Bgr24 , у вас все должно быть в порядке.

Итак, у вас должно быть:

cfg.EnableStream(Stream.Color, 640, 480, format: Format.Bgr8);

и

new WriteableBitmap(p.Width, p.Height, 96d, 96d, PixelFormats.Bgr24, null);

Я не думаю, что вам нужно будет изменять System.Drawing.Bitmap формат пикселей, поскольку вы используете его только для загрузки OpenCV mat .

Комментарии:

1. Я пытался найти эти форматы, которые вы упомянули, но они недоступны в настройках. Вы имеете в виду изменить эти местоположения? « imgColor. Источник = новая карта BITMAP для записи (p.Width, p.Height, 96d, 96d, PixelFormats.Rgb24, null); Система. Рисование. Bitmap ColorImg = новая система. Рисование. Растровое изображение (цветной кадр. Ширина, цветовая рамка. Высота, цветовая рамка. Шагайте, система. Рисование. Визуализация. Формат пикселей. Формат24bppRgb, colorFrame.Data); «