拍摄一次并显示之前的捕获 - VB - OpenCV



我在使用网络摄像头,opencv和emgucv捕获图片时遇到特殊问题。

我以前用过这个功能,一直运行良好,但现在,我不知道为什么,图片框正在向我显示之前拍摄的照片。让我解释一下:

我启动程序 - 我按下按钮并在拍照前等待几秒钟 - 我使用 img = capturez 拍摄照片。QueryFrame() - 我在图片框中显示图片。这是代码:

Private Sub startButton_Click() Handles startButton.Click
Dim timeToWait As Integer
PictureBox1.Image = Nothing
If globalGMT <> Nothing And globalLatitude <> Nothing And globalLongitude <> Nothing Then
'If TextBox_GMT.Text IsNot Nothing And TextBox_LAT.Text IsNot Nothing And TextBox_LON.Text IsNot Nothing Then
SunPosition(globalGMT, globalLatitude, globalLongitude, ELEVACIONDELSOL, AZIMUTDELSOL)
End If
startButton.Enabled = False
SetDefaultTimeButton.Enabled = False
SetParameters.Enabled = False
TextBoxTime.Text = System.DateTime.UtcNow
timeToWait = globalTimeLeft
For i = 0 To timeLeft
wait()
i += 1
timeToWait -= 1
timeLabel.Text = timeToWait & " seconds"
Next
Dim img As Image(Of Bgr, Byte) = capturez.QueryFrame()
For x = 0 To img.Width - 1
For y = 0 To img.Height - 1
Dim pixelColor As Bgr = img(y, x)
If (pixelColor.Blue >= 200 And pixelColor.Blue <= 255) And
(pixelColor.Green >= 200 And pixelColor.Green <= 255) And (pixelColor.Red >= 200 And pixelColor.Red <= 255) Then
pixelColor.Blue = 255
pixelColor.Green = 255
pixelColor.Red = 255
img(y, x) = pixelColor
Else
pixelColor.Blue = 0
pixelColor.Green = 0
pixelColor.Red = 0
img(y, x) = pixelColor
End If
Next
Next
PictureBox1.Image = img.ToBitmap
startButton.Enabled = True
SetParameters.Enabled = True
SetDefaultTimeButton.Enabled = True
SetForm()
End Sub

函数wait()看起来像这样:

Private Sub wait()
Dim seconds As Integer = 1
For i As Integer = 0 To seconds * 100
System.Threading.Thread.Sleep(10)
'Application.DoEvents()
Next
End Sub

也许你可以问,你为什么不使用计时器呢?这是因为使用计时器我遇到了完全相同的问题。以下是使用计时器的代码:

'This function will start the activity of the form
Private Sub startButton_Click() Handles startButton.Click
Dim timeToWait As Integer
PictureBox1.Image = Nothing
If globalGMT <> Nothing And globalLatitude <> Nothing And globalLongitude <> Nothing Then
'If TextBox_GMT.Text IsNot Nothing And TextBox_LAT.Text IsNot Nothing And TextBox_LON.Text IsNot Nothing Then
SunPosition(globalGMT, globalLatitude, globalLongitude, ELEVACIONDELSOL, AZIMUTDELSOL)
End If
startButton.Enabled = False
SetDefaultTimeButton.Enabled = False
SetParameters.Enabled = False
TextBoxTime.Text = System.DateTime.UtcNow
StartButtonTimer.Start()
End Sub
'This function will start the timer of the form 
Private Sub StartButtonTimer_Tick() Handles StartButtonTimer.Tick
Dim X As Integer
Dim Y As Integer
If timeLeft > 0 Then
timeLeft -= 1
timeLabel.Text = timeLeft & " seconds"
'DLE prueba tomar foto después del tiempo especificado - pongo a negro el fondo del picturebox
PictureBox1.BackColor = Color.Black
Else
'DLE prueba tomar foto después del tiempo especificado - hago foto de lo que ve la camara
Dim img As Image(Of Bgr, Byte) = capturez.QueryFrame()
For X = 0 To img.Width - 1
For Y = 0 To img.Height - 1
Dim pixelColor As Bgr = img(Y, X)
If (pixelColor.Blue >= 200 And pixelColor.Blue <= 255) And
(pixelColor.Green >= 200 And pixelColor.Green <= 255) And
(pixelColor.Red >= 200 And pixelColor.Red <= 255) Then
pixelColor.Blue = 255
pixelColor.Green = 255
pixelColor.Red = 255
img(Y, X) = pixelColor
Else
pixelColor.Blue = 0
pixelColor.Green = 0
pixelColor.Red = 0
img(Y, X) = pixelColor
End If
Next
Next
StartButtonTimer.Stop()
PictureBox1.Image = img.ToBitmap
startButton.Enabled = True
SetParameters.Enabled = True
SetDefaultTimeButton.Enabled = True
SetForm()
End If
End Sub

函数 SetForm() 只启用某些按钮。

问题是: 我拍第一张照片 - 图片框显示第一张照片。 我拍第二张照片 - 图片框再次显示第一张图片。 我拍第三张照片 - 图片框显示第二张照片。 我拍第四张照片 - 图片框显示第三张照片。 ... ... 拍照后,我只识别一种颜色,并将该颜色显示为白色,其余部分显示为黑色(如果有人需要此解释)

感谢您给我的任何帮助!

编辑:如果我在函数末尾添加这一行:将图像调暗为图像(Bgr,字节)= capturez。QueryFrame(),它运行良好:

...
...
Next
StartButtonTimer.Stop()
PictureBox1.Image = img.ToBitmap
startButton.Enabled = True
SetParameters.Enabled = True
SetDefaultTimeButton.Enabled = True
SetForm()
End If
Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame()
End Sub

结束类

我不白使用最后一个变量,只是我在声明它而不使用它。我不明白为什么这条线效果很好,当我擦除它时,它不起作用。.

我花了一段时间才弄清楚这一点,但我相信问题是你没有Dispose你的捕获。由于您只在单击按钮时捕获一帧(并且您没有实时网络摄像头流),因此您应该在使用后DisposeCapture对象。现在发生的情况是,您请求一个新帧,Capture对象将返回旧帧,然后开始检索另一个准备下次使用的帧。因此,如果您在方法末尾放置另一个QueryFrame(),它将再次工作,因为旧框架被覆盖。

这应该可以解决您的问题:

'Make sure you can use your retrieved image even after the dispose
Dim img As Image(Of Bgr, Byte);
'Create a new capture object
Using capturez As New Capture
'Since it's a new object the webcam is forced to retrieve a frame now
'Also, use Copy() to make sure your image is still available after diposing
img = capturez.QueryFrame().Copy()
End Using 'Dispose the object now 
'Now do with your img object whatever you want!

最新更新