在循环中创建图像时实时显示图像

时间:2016-12-18 06:27:22

标签: c# real-time emgucv

在我的代码中,输出是一个图像,其每个像素都是使用嵌套循环确定的。

1)如何在循环中构建输出图像时强制窗口打开并显示输出图像? (当一切都完成时,窗口会出现。我不想要这个。)

2)当循环继续时,如何逐行(或甚至逐像素)显示输出。用户必须具有实时获取输出的意识。

    outImage = new Image<Hsv, Byte>(numberOfColumns, numberOfRows);
    byte[,,] pixelValue = outImage.Data;
        for (int i = 0; i < numberOfRows - 1; i++)
        {
            for (int j = 0; j < numberOfColumns - 1; j++)
            {
                //pixelValue[i, j, k] is determined here using some other functions
                imageBox1.Image = outImage; //too slow and impossible                 
            }
        }

3 个答案:

答案 0 :(得分:1)

您可以通过将图像放在单独的线程上并使用GetPixelSetPixel来实时逐像显示图像。请记住,虽然这些方法很慢,但如果要显示高分辨率图片,则需要一段时间。

您要做的是创建一个带有图片框控件的表单。接下来,创建一个包含您要显示的图像的Bitmap对象。您可以使用以下行来执行此操作:

Bitmap _bmp = new Bitmap(Image.FromFile(@"C:\MyImage.jpg"));

接下来,在您的表单的shown事件中,分离一个新任务来完成工作,因此GUI不会锁定:

private void Form1_Shown(object sender, EventArgs e)
{
    Task.Factory.StartNew(ShowImage);
}

每次显示表单时,此行将分拆一个新线程。该线程将分叉并调用ShowImage(),它应如下所示:

private void ShowImage()
{
    Graphics g = pbImage.CreateGraphics();

    for (int x = 0; x < _bmp.Width; x++)
    {
        for (int y = 0; y < _bmp.Height; y++)
        {
            Color c = _bmp.GetPixel(x, y);
            if (pbImage.InvokeRequired)
            {
                var x1 = x;
                var y1 = y;
                pbImage.BeginInvoke((Action) (() =>
                {
                    g.FillRectangle(new SolidBrush(c), x1, y1, 1, 1);
                }));
            }
            else
            {
                g.FillRectangle(new SolidBrush(c), x, y, 1, 1);
            }
            System.Threading.Thread.Sleep(1);
        }
    }
}

如果你想加快这一点,你可以启动两个或更多任务,每个任务并行工作(例如,一个线程从头开始,另一个在末尾,另一个在中间可能,等等)。只要确保你的线程没有“重叠”。

另一种加快速度的方法是使用指针代替GetPixel()SetPixel()。您必须将代码标记为unsafe

答案 1 :(得分:0)

将您的代码放在后台Worker =&gt;做工作 将启动一个单独的线程

答案 2 :(得分:-1)

我不是WinForms专家我更像是WPF类型。但我有一个运行稳定的30fps的应用程序,这比人类可以检测到的更快。我真的不太明白你想做什么。你必须单独blit每个像素,但实时显示? ImageBox派生自Windows Forms PictureBox,这是我不认为的工作。

您可以尝试移动到WPF,并使用WriteableBitmap作为ImageSource的ImageSource或Canvas对象的背景。 WriteableBitmap允许您访问每个像素,但刷新率由WPF控制,显示器刷新率由AC当前频率控制。

道格