我正在使用Allied Vision Vimba相机来监控涉及激光的实验。
我编写了一个代码,允许我从相机实时成像中取一帧(以pictureBoxFixe1
显示,黑白),将其放入另一个PictureBox(button-click
)并继续工作它。代码在大多数情况下工作正常,即使它没有完成。
我的问题是,最终,我需要连续工作,意味着从相机的每一帧(大约每秒15-20),我开始觉得这将是复杂的。
我并没有要求你帮助我完成整个过程,但我有一个不起作用的确切例子,我想理解。我正在使用Vimba .NET API,因此大多数人可能都不熟悉所调用的一些函数(对我来说它们并不是很多,真的),但我会尽力在代码中解释它们(API手册有点神秘)。
我的代码有一个部分,当我从相机中隔离一帧以对其进行处理时(通过private void fixButton_Click(object sender, EventArgs e)
{
if (m_Acquiring == true) //mm_Acquiring being true indicates that the camera is sending images continuously, and that they are toggled in pictureBoxLiveCamera
{
pictureBoxFixe1.Image = SaveBitmap; //SaveBitmap is the bitmap isolated from the live camera in an earlier code portion
Array.Clear(PixelColorCount, 0, 256);
foreach (var Series in chartHist.Series)
{
Series.Points.Clear();
}
//Creating a bitmap from pictureBoxFixe1 to draw the histogram from
Bitmap Couleur = new Bitmap(pictureBoxFixe1.Image);
//Collecting data from pictureBoxFixe1
for (int i = 0; i < 1023; i++)
{
for (int j = 157; j < 288; j++)
{
PixelColorCount[Couleur.GetPixel(i + 1, j).B] += 1;
}
for (int j = 484; j < 615; j++)
{
PixelColorCount[Couleur.GetPixel(i + 1, j).B] += 1;
}
}
//Plotting the pixel counter, to detect saturation
for (int i = 0; i < 256; i++)
{
chartHist.Series["Pixel count"].Points.AddXY(i, PixelColorCount[i]);
}
//If there are saturated pixels : toggle a title on chart 1 to warn the user
if (PixelColorCount[255] > 1)
{
chartHist.Titles["Title1"].Visible = false;
chartHist.Titles["Title2"].Visible = true;
}
else
{
chartHist.Titles["Title1"].Visible = true;
chartHist.Titles["Title2"].Visible = false;
}
}
else
{
MessageBox.Show("Acquisition is not running.", "Something went wrong !", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
事件,绘制一个直方图,绘制垂直轴上的像素数和数字数值水平轴。这样我知道是否有些像素是饱和的(在255处),我可以降低曝光时间。这很好用,这里是按钮的代码,它隔离一帧并绘制直方图:
private void BtAcquisitionLiveCam_Click(object sender, EventArgs e)
{
//Here is the part of the code that starts the live acquisition when I click the button, I don't copy it completely because I don't think this is relevant.
this.m_Acquiring = true;
mycamera.OnFrameReceived += new Camera.OnFrameReceivedHandler(this.OnFrameReceived); //This is the event handler for the reception of a frame for the camera, it is part of the Vimba API
mycamera.StartContinuousImageAcquisition(1); //According to the manual, this "Starts streaming and allocates the needed frames", with the argument being "count of Frame(s) which should be used for this method"
}
private void OnFrameReceived(Frame frame) //Frame is the class in which the code puts the data from the camera, frame is the last pack of data received from the camera
{
Bitmap myBitmap = null;
if (true == m_Acquiring)
{
try
{
mycamera.QueueFrame(frame);
}
catch (Exception)
{
MessageBox.Show("Frame queuing failed.", "Something went wrong !", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else
{
MessageBox.Show("Acquisition is not running.", "Something went wrong !", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
featureExposureTime.FloatValue = (double)hScrollBarLiveExposureTime.Value;
frame.Fill(ref myBitmap);
pictureBoxLiveCamera.Image = myBitmap;
SaveBitmap = myBitmap; //Up until here the code works perfectly, because I can use SaveBitmap without problem later in the code (not shown here)
Array.Clear(PixelColorCount, 0, 256);
foreach (var Series in chartHist.Series)
{
Series.Points.Clear();
}
//Collecting data from pictureBoxFixe1
for (int i = 1; i < 1023; i++)
{
for (int j = 1; j < 767; j++)
{
PixelColorCount[SaveBitmap.GetPixel(i, j).B] += 1;
}
}
//Plotting the pixel counter, to detect saturation
for (int i = 0; i < 256; i++)
{
chartHist.Series["Pixel count"].Points.AddXY(i, PixelColorCount[i]);
}
//If there are saturated pixels : toggle a title on chart 1 to warn the user
if (PixelColorCount[255] > 1)
{
chartInit.Titles["Title1"].Visible = true;
}
else { }
}
现在我想要的是让这个工作生动,每一帧从相机传入。但它不起作用,我找不到原因。这是我试过的:
ERROR in src/app/rcyc-components/rcyc-channels/rcyc-channels.component.ts(53,44): error TS2339: Property '_urlSegment' does not exist on type 'ActivatedRouteSnapshot'.
很抱歉代码的数量,但我想我不能这样做。我的问题是直方图根本没有显示(它被设置为可见,我看到了标题,但没有任何内容被绘制在其中)。有没有人有任何想法?
让我发疯的事情是,随相机提供的VimbaViewer程序完全按照我想要的方式完成,但我无法访问它的源代码......
谢谢!
答案 0 :(得分:0)
如果我正确关注,您的OnFrameReceived事件正在正确触发,但在处理完每个帧后WinForm应用程序UI没有更新。
看起来&#34; chartInit&#34;在你的OnFrameReceived中被引用而不是&#34; chartHist&#34;,那应该是这种情况吗?
无论您的图表控件是什么,请尝试&#34; chart.Refresh()&#34;或者&#34; chart.Update()&#34;。它可能不是从事件循环更新UI线程。
您需要考虑的另一件事是这些图像的速度有多快。它会以每秒15-20次的速度绘制和重绘图表吗?这合理吗?可能需要某种队列/平均机制来仅每x秒更新一次图表,或者如果相对于图像的变化超过某个阈值,则可能需要。只是一个想法。