我正在使用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
循环无限期地运行。这可能就是问题所在。