【问题标题】:How to process video frames in different thread (C#)如何在不同的线程中处理视频帧(C#)
【发布时间】:2015-04-06 03:51:08
【问题描述】:

背景

我正在开发一个应用程序,该应用程序需要对视频流进行一些图像处理,并并排显示原始视频和处理后的视频。

情况

以下是从相机接收到新帧时的事件处理程序。 pictureBox1是显示原始视频的位置。 GetInputImage() 函数会从 pictureBox1 中窃取一个,以便对该帧进行一些图像处理。

private void camera_NewFrame(object sender, ref Bitmap image)
{
    if (!isReadingPictureBox)
    {
       if (pictureBox1.Image != null)
           pictureBox1.Image.Dispose();
       pictureBox1.Image = (Bitmap)image.Clone();
    }
}

private void GetInputImage()
{
    if (inputImage != null)
        inputImage.Dispose();

    isReadingPictureBox = true;
    if (pictureBox1.Image != null)
        inputImage = new Bitmap(pictureBox1.Image);
    isReadingPictureBox = false;
}

图像处理繁重,处理单个图像需要时间。因此输出视频的帧率预计会比原始视频低很多。

应用程序必须在不受图像处理影响的情况下显示原始视频。所以我想在不同的线程中执行图像处理。

private void ProcessThread(some args)
{
    GetInputImage();
    if (inputImage != null) {
        // Do Image Processing on "inputImage"
        // Show result in pictureBox2
    }
}

问题

[1] 抓帧的方法(上)好吗?还是下面那个更好?

private void camera_NewFrame(object sender, ref Bitmap image)
{
    pictureBox1.Image = image; // picturBox1's image will not be read for processing

    if(!isReadingInputImage) {
        if (inputImage != null)
            inputImage.Dispose();
        inputImage = (Bitmap)image.Clone(); // GetInputImage() is not required now.
    }
}

[2] 如何使ProcessMyThread(),为每个运行 前一帧完成处理时可用的帧?这(下)方法可以吗?

private void ProcessMyThread(some args)
{
    do {
        GetInputImage();
        if (inputImage != null) {
            // Do Image Processing on inputImage;
            // Show result in pictureBox2
        }
    }while(someCondition);
}

或者我应该为camera_NewFrame() func 中的每个帧触发一个处理事件?

【问题讨论】:

  • 您可以使用Queue 顺序处理您的图像。只需将它们加入您的ProcessThread() 并触发对ProcessMyThread() 的调用,这会将图像排入队列并一张一张地处理它们。如果Queue 已经在处理,您可以简单地在ProcessMyThread() 中不做任何事情(您可以使用布尔值来跟踪)
  • 感谢您的帮助,但队列没有帮助。 (见下面我的解决方案) A. 在多线程中使用队列,循环回到我开始的问题。 B. 正如我所提到的,图像处理很繁重,因此产生的帧速率非常低(2 fps)。我不希望处理所有帧(队列可能就是这种情况)。

标签: c# .net multithreading image-processing video-processing


【解决方案1】:

我自己使用后台工作者解决了这个问题。

private void camera_NewFrame(object sender, ref Bitmap image)
{
    pictureBox1.Image = image;

    if (backgroundWorker1.IsBusy != true)
    {
        lock (locker)
        {
            if (inputImage != null)
                inputImage.Dispose();
            inputImage = (Bitmap)image.Clone();
        }
        backgroundWorker1.RunWorkerAsync();
    }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    lock (locker)
    {
         baseImage = (Bitmap)inputImage.Clone();
    }
    // Do Image processing here on "baseImage"
    // show result in pictureBox2
}

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2011-03-29
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多