【问题标题】:Trying to obtain gray images from webcam using Visual Basic, OpenCV and EmguCV尝试使用 Visual Basic、OpenCV 和 EmguCV 从网络摄像头获取灰度图像
【发布时间】:2017-08-25 11:01:45
【问题描述】:

我正在学习 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 ...

非常感谢!

【问题讨论】:

  • 接受答案会将问题标记为“已解决”。您无需将其弹出到标题中。尽可能保持清洁。

标签: vb.net opencv image-processing emgucv


【解决方案1】:

目前您正在捕获彩色图像 (BGR),因此您不能只在 Picturebox 中显示一个通道,因为这不是 GrayScale 图像(它是 Blue 通道,因为这是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 个通道,等等)。因此,第二个选项可能更适合您,因为您现在将拥有 BgrGrayScale。您现在仍然可以使用Bgr 图像进行HSV 转换等。

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

PictureBox1.Image = imgGrayscale.ToBitmap()

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

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

  • 检索您的Bgr 图像并将其转换为Hsv
  • 不要将你的图像分成三个通道,而只是创建一个新的空图像来存储你的颜色阈值结果
  • 调用CvInvoke.InRange 函数,但将标量应用于所有三个HSV 通道。我建议使用 InRange 而不是 InRangeS,因为后者来自 OpenCV 1.X。
  • InRange 函数的工作方式如下:MCvScalars 表示颜色值在HSV 范围内的边界。它检查每个像素并比较它是否在您声明的标量值内。如果是,它将获得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)

【讨论】:

  • 非常感谢NuclearPenguin!现在我有我的灰度图像!请让我再问你一件事。如果我只想获得一种颜色,例如白色或黄色,该怎么办?我的意思是,我想要获得的颜色转换为白色,其余颜色转换为黑色。我必须从该灰度图像中进行操作,还是必须从 bgr 图像中进行操作?示例:我想从太阳拍摄一张照片,但我只想看到白色的太阳,其余的颜色为黑色。我希望你能帮助我!
  • 不客气!如果要提取一种颜色并对其进行阈值化,则必须采取不同的步骤(您已经走在正确的轨道上)。它很长,所以我将它添加到我的原始答案中。我希望这涵盖了您的所有问题!此外,如果此答案解决了您的问题,请不要忘记接受它作为答案。
  • 最后我提取了一种颜色!!哈哈..在这个线程中我已经发布了另一个问题,如果你想看到它,你可以看看我是如何实现的。非常感谢! stackoverflow.com/questions/43211664/…
猜你喜欢
  • 2014-03-19
  • 2013-12-15
  • 1970-01-01
  • 2016-03-05
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多