使用Vimba API实时更新图表

时间:2018-04-30 12:42:04

标签: c# camera

我正在使用vimba相机,我正在尝试设置一个直方图,该直方图会更新来自相机的每一帧,以便检测像素的饱和度(颜色值= 255)。来自摄像机的帧中帧被放置在具有PixelFormat = fromat8bppIndexed(灰度)的位图中,速率为15-20 FPS。

我的直方图的工作方式如下:我从位图锁定位,扫描图像,检索每个像素的颜色信息,并递增数组中的相应索引(例如:如果像素有颜色强度为126,我将数组[126]增加一个)。在扫描结束时,我有一个数组[256],其每个值对应于具有该特定颜色强度的像素数。然后,我必须使用数组索引作为X绘制直方图,并将数组值绘制为y。我在随机位图(不是来自相机)上测试了代码,它运行得很好。

直方图代码放在Vimba API的OnFrameReceived(Frame)函数内,使用如下:"当帧缓冲区填充数据时,将触发事件" (来自Vimba API手册)。我知道委托没有问题,因为函数内部的部分代码工作正常。

我使用GetPixels编写了以前版本的代码,但我读到这是从图像中检索数据的一种非常慢的方式,因此我转而使用LockBits。我知道我的语法正确,因为我在OnFrameReceived函数之外测试了它,并且它的工作方式(比GetPixels更快)。

现在我的问题是,当我开始采集时,直方图不会填充数据。

以下是代码:

    private void OnFrameReceived(Frame frame)
    {
        Bitmap myBitmap = null;
        if (true == m_Acquiring)
        {
            mycamera.QueueFrame(frame);
        }

        frame.Fill(ref myBitmap);
        pictureBoxLiveCamera.Image = myBitmap;
        SaveBitmap = myBitmap; //Up to here the code works perfectly, as I can use SaveBitmap correctly later in my program

        //Emptying chartInit
        Array.Clear(PixelColorCount, 0, 256);
        foreach (var Series in chartHist.Series)
        {
            Series.Points.Clear();
        }

        //Retrieving pixels data
        unsafe
        {
            int width = SaveBitmap.Width;
            int height = SaveBitmap.Height;
            int bytesPerPixel = 1;
            int maxPointerLength = width * height * bytesPerPixel;
            int stride = width * bytesPerPixel;
            System.Drawing.Imaging.BitmapData bData = SaveBitmap.LockBits(new System.Drawing.Rectangle(0, 0, SaveBitmap.Width, SaveBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, SaveBitmap.PixelFormat);
            byte* scan0 = (byte*)bData.Scan0.ToPointer();
            byte B;
            for (int i = 1; i < maxPointerLength; i++)
            {
                    B = scan0[i];
                    PixelColorCount[B] += 1;
            }
            SaveBitmap.UnlockBits(bData);
        }

        //Plotting the pixel counter, to detect saturation
        for (int i = 0; i < PixelColorCount.Length; i++)
        {
            chartHist.Series["Pixel count"].Points.AddXY(i, PixelColorCount[i]);
        }
    }

有没有人知道我的代码有什么问题?如果没有什么不对的话,这可能与计算时间长,帧刷新太快有关吗?如何检查?我该怎么做才能解决它?

谢谢!

编辑:在按钮点击事件中触发对OnFrameReceived事件的调用,这是带有处理程序的代码:

            this.m_Acquiring = true;
            mycamera.OnFrameReceived += new Camera.OnFrameReceivedHandler(this.OnFrameReceived);
            mycamera.StartContinuousImageAcquisition(1);

我刚刚对代码中的细分点进行了一些测试,似乎Emptying chartInit部分运行(达到了细分点),但foreach循环无限期地运行。这可能就是问题所在。

0 个答案:

没有答案