vb.net - 尝试使用 Visual Basic、OpenCV 和 EmguCV 从网络摄像头获取灰度图像

标签 vb.net opencv image-processing emgucv

我正在学习 OpenCV 和 EmguCV。我通过尝试从我的网络摄像头获取图像而获得成功,现在我正在尝试获取灰度图像。

实现此目标后,我的目的是识别和跟踪颜色,因此我尝试以 HVS 格式获取图像以过滤图像以仅显示我在白色中寻找的颜色,而图像的其余部分为黑色(希望你能理解我的解释)

现在,我只想使用以下代码从我的网络摄像头获取灰度图像:

Imports Emgu.CV

Imports Emgu.CV.Util

Imports Emgu.CV.Structure

Imports System.Drawing

Public Class Form1

Dim capturez As Capture = New Capture
Dim radius As Decimal = 50.0F
Dim x As Decimal
Dim y As Decimal

Private Sub Timer1_Tick() Handles Timer1.Tick

    'Define x and y to determinate the position of the circle in the PictureBox
    x = PictureBox1.Width / 2 - radius
    y = PictureBox1.Height / 2 - radius

    'PointF type defines the X and Y position of the future circle in the PictureBox
    Dim point1 As New PointF(x, y)
    Dim circle As CircleF = New CircleF(point1, radius)
    Dim img As Image(Of Bgr, Byte) = capturez.QueryFrame()

    'Convert camera capture from BGR to HVS
    Dim hvs_frame As Image(Of Hsv, Byte) = img.Convert(Of Hsv, Byte)()

    'Obtain the three channels that compose the HVS image (hue, saturation and value)
    Dim channels As Image(Of Gray, Byte)() = hvs_frame.Split()


    'Remove all pixels from the hue channel that are not in the range [40, 60]
    CvInvoke.cvInRangeS(channels(0), New Gray(200).MCvScalar, New Gray(255).MCvScalar, channels(0))

    'Display converted frame
    PictureBox1.Image = channels(0).ToBitmap()

    'When commenting the .CopyBlank() property, the back color of the PictureBox remains transparent
    'When uncomment this, the back color of the PictureBox becomes black
    Dim imageCircle As Image(Of Bgr, Byte) = img '.CopyBlank()
    imageCircle.Draw(circle, New Bgr(Color.Brown), 2)
    PictureBox1.Image = imageCircle.ToBitmap()
End Sub

使用此代码,我只能获取 BGR 中的图像,我不知道为什么,因为我在“PictureBox1.Image”中指定我想要该灰度图像。

请帮帮我=(

我正在使用 OpenCV 2.4.9 和 EmguCV 2.4.0 ... 如果需要的话

非常感谢!

最佳答案

目前您正在捕获彩色图像 ( BGR ),因此您不能只在 Picturebox 中显示一个 channel 因为这不会是 GrayScale图像(它是 Blue channel ,因为它是 BGR 图像)。您可以通过两种方式解决此问题。

第一个选项是在 GrayScale 中专门从您的相机中检索帧.你可以这样实现:

Dim imgGrayscale As Image(Of Gray, Byte) = capturez.RetrieveGrayFrame()

另一种选择是将图像转换为 GrayScale从网络摄像头捕获中检索到它之后。你可以这样实现:

Dim img As Image(Of Bgr, Byte) = capturez.QueryFrame()
Dim imgGrayscale As Image(Of Gray, Byte) = img.Convert(Of Gray, Byte)()

请注意,从这一刻起,您将使用 GrayScale图像,这将影响您的其余代码(即您将不再有 3 个 channel ,等等)。因此,第二个选项可能更适合您,因为您现在将拥有一个 Bgr。和一个 GrayScale .您现在仍然可以使用 Bgr图片为您 HSV转换等

您现在可以显示 GrayScale像这样的图像:

PictureBox1.Image = imgGrayscale.ToBitmap()

编辑为一种颜色的阈值,而不是转换为灰度:

如果你想从图像中提取一种颜色,你不能使用 Grayscale ,即使结果将是单 channel 图像。这是因为您需要所有 channel 值来提取正确的颜色。请按照以下步骤操作:

  • 找回你Bgr图像并将其转换为 Hsv和你一样。
  • 不要将您的图像分成三个 channel ,而只是创建一个新的空图像来存储您的颜色阈值结果
  • 调用CvInvoke.InRange函数,但将标量应用于所有三个 HSV channel 。我推荐使用 InRange而不是 InRangeS因为后者来自 OpenCV 1.X。
  • InRange函数的工作原理如下:MCvScalarsHSV 中表示颜色值的边界范围。它检查每个像素并比较它是否在您指定的标量值范围内。如果是,它将获得 255像素值(白色),否则 0 (黑色的)。这将为您提供阈值图像。
  • 如果你想提取更多的颜色范围,你可以添加更多CvInvoke.Inrange方法并使用 CvInvoke.Add 添加不同的结果稍后发挥作用。
  • 使用 MCvScalar 进行实验如果他们没有给你正确的结果,你设置的边界来提取你的颜色。此外,如果您想获得不同的颜色,请修改边界。您可以使用颜色选择器检索 HSV某些颜色的值。即使是 MS Paint 中的颜色选择器也会为您提供 Hue/Sat/Lum值,但您必须转换这些值(它们的比例不同,MS Paint 0-239OpenCV 0-179 )。因此,通过将级别乘以 180/240 来转换它们.

你会得到这样的东西:

` Get the webcam frame
Dim webcam_image As Mat
webcam_image = capturez.QueryFrame()

` Get an empty HSV image and threshold image
Dim HSV_img As New Mat(webcam_image.Size, DepthType.Cv8U, 3)
Dim threshold_img As New Mat(webcam_image.Size, DepthType.Cv8U, 1)

' Convert camera capture from BGR to HVS
CvInvoke.CvtColor(webcam_image, HSV_img, ColorConversion.Bgr2Hsv)

` Threshold the yellow colors only (please adopt the scalar values to whatever values suit your needs)
CvInvoke.InRange(HSV_img, New ScalarArray(New MCvScalar(20, 100, 100)), New ScalarArray(New MCvScalar(30, 255, 255)), threshold_img)

关于vb.net - 尝试使用 Visual Basic、OpenCV 和 EmguCV 从网络摄像头获取灰度图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43136176/

相关文章:

c# - 是否可以在 .NET 中以彩色方式写入控制台?

vb.net - 是否可以在 VB .NET 中声明一个动态常量?

android - 找不到 opencv.hpp?安卓NDK

python - 如何在 python 中裁剪和旋转图像的一部分?

python - 测量图像中文本边框的直/平滑度

asp.net - 将网站转换为 Web 应用程序问题

.net - 如何使用 VB.net 从 Excel 中的范围对象获取单元格引用?

python - 从源代码安装opencv时,如何在pyinstaller中包含OpenCV?

image - 如何基于二进制掩码裁剪图像

Python 图像文本标签脚本