使用 EmguCV 从 IP 摄像机捕获帧

Capture frames from IP camera using EmguCV

也许标题已经被使用了很多次,但是我在 Google 上找到的任何答案都给了我正确的答案,所以我将在这里解释我的问题:

我有一个 IP 摄像头,使用它自己的程序可以完美地工作,所以我知道摄像头工作正常。我已将网络摄像机设置为具有静态 IP,因此它始终具有相同的 IP 地址。我成功地从网络摄像头获取帧,使用:

Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame()

而且我知道 QueryFrame() 方法有 3 种使用方式:

Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame()
Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame(int)
Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame(string)

我正在尝试这样做:

Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame("rtsp://192.168.1.3/img/video.sav")

很多人说这行得通,但不适合我。我在其他论坛也看到过这个:

Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame("rtsp://user:pass@192.168.1.3/img/video.sav")

万一网络摄像机附加了用户名和密码(我就是这种情况),但仍然无法使用。

我得到的错误是: 'a value with type emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) can not be converted in Emgu.CV.Image(Of Emgu.CV.Image(Of Emgu.CV.Structure.Bgr, Byte)'

我不知道为什么会出现此错误。我想我得到这个是因为 Capture.QueryFrame() 正在捕获类型为 Emgu.CV.Structure.Gray 并且它不能转换为另一个,但我不知道我是否正确。

如果我是对的,我不知道如何保存 Capture.QueryFrame()

拍摄的图像

如果我不正确,那么我不知道为什么会收到该错误。

我见过其他人使用这样的东西:

Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame("http://192.168.1.3:port/img/video.sav")

但是网络摄像机没有联网。它通过局域网连接,直接连接到我的电脑。我已经配置了我的计算机的 IPv4 配置和我的 IP 摄像机的设置,使其在没有互联网连接的情况下工作,正如我之前所说,它使用自己的程序工作。

我希望你有所有需要的细节来理解我的问题。如果不是,请告诉我,我试着用另一种方式解释。

Resuming:我有一个网络摄像头,我想用它拍一张照片(不是视频流,只有当我决定拍的时候才拍一张照片),我使用的是 Emgu 2.4.0、Visual Basic 和 VS2012 .我不知道如何使用 QueryFrame() 方法

最后,如果可能的话,有人能告诉我那是什么意思吗

../img/video.sav

每个人都输入了字符串?它是我计算机中必须有的目录还是类似的目录?

如果有帮助,我将方法放在我尝试进行此捕获的地方。在其中,我试图捕获一个帧并在 PictureBox 中显示图像的白色,其余部分为黑色:

 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

    'Old frame is overwritten so that the most current image is always ready to retrieve
    Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame()


End Sub

非常感谢您的帮助!!我快被这个搞疯了!!

编辑: 在 AForge 库和论坛中进行了一些研究,我看到了这个线程,其中一个人解释了他如何使用该库从 IP 摄像机拍摄图像。我在我的计算机上安装了用于其他项目的库,但我不知道我可以将这些库用于我的目的。

这是话题: http://emgu.com/forum/viewtopic.php?t=4199

我去看过他建议看的项目,在Samples目录下找到了一个叫Player的项目,就是用这个方法打开一个camera的url来显示它在看什么:

// Open MJPEG URL
    private void openMJPEGURLToolStripMenuItem_Click( object sender, EventArgs e )
    {
        URLForm form = new URLForm( );

        form.Description = "Enter URL of an MJPEG video stream:";
        form.URLs = new string[]
            {
                "http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=4",
                "http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=3",
            };

        if ( form.ShowDialog( this ) == DialogResult.OK )
        {
            // create video source
            MJPEGStream mjpegSource = new MJPEGStream( form.URL );

            // open it
            OpenVideoSource( mjpegSource );
        }
    }

我正在研究它是如何工作的,但我不明白为什么它以这种方式使用这些行:

"http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=4",
"http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=3",

我的意思是,我知道我必须把相机的 url 放在这个例子的 url 中。在我的例子中,我的网络摄像机是 192.168.1.3,所以它必须是这样的:

"http://192.168.1.3/axis-cgi/mjpg/video.cgi?camera=4"

但是,关于该行的其余部分,我的意思是:

.../axis-cgi/mjpg/video.cgi?camera=4

他们为什么放这个?我不知道如何在我的相机中找到这些信息。我只有一台通过 IP 连接的摄像机,所以我必须放在那里什么?这是我必须创建的目录还是类似的目录?

编辑: 关于以上内容,经过更多调查后,我发现 url 的其余部分指定了我的图像存储路径。在尝试找到我的相机离开图像的路径后,我无法找到它,也找不到用户指南,也无法上网。我找不到那个路径 =(。有人知道如何找到它吗?

非常感谢!!

我使用的工具:EmguCV 2.4.0、vs2012、网络摄像机:ETROVISION EV6131HW、Visual Basic

上次编辑 - 解决方案: 大家好!我终于找到了所有问题的解决方案,所以我 post 如果有人觉得有用,我会把它放在这里。

关于我的第一个问题,我问的是 QUeryFrame():

方法内部的 url
Dim image As Image(Of Bgr, Byte) = capturez.QueryFrame("rtsp://192.168.1.3/img/video.sav")

我看了很多这方面的资料,我的结论是这个 url 是由制造商指定的,通常在相机的数据表中指定,所以它既不是发明的 url ,也不是存储图像的文件夹。看一个例子,你可以在下面的url中看到,不同相机使用的一些url:

Link for url of different cameras

所以,在变量的声明中只写相机的特定url,一定足以实现与相机的连接。我通过使用安讯士相机并查看其数据表来实现这一点。就我而言,这是 url:

Dim capturez As Capture
capturez = New Capture("rtsp://192.168.0.90/axis-media/media.amp?videocodec=H264")

我做的下一个问题:

If I am right, I dont know how to save that image taken by the Capture.QueryFrame()

这很容易。 QueryFrame方法返回的图片,必须保存在Image类型的变量中,像这样:

Dim img As Image(Of Bgr, Byte) = capturez.QueryFrame
    PictureBox1.Image = img.ToBitmap()

    'If you want to store the image of the PictureBox
    PictureBox1.Image.Save("f:\picture.bmp")

    'If you want to store the image stored in the variable img
    imageToProcess.Save("f:\picture.bmp")

存储的文件,必须有扩展名.bmp,因为你存储的是位图图像(我对此完全不确定所以如果有人可以确认,我会在需要时编辑它)

关于我在这里所说的:

But the IP camera is not connected by internet. It is connected by LAN, directly to my computer. I have configured the IPv4 config of my computer, and the settings of my IP camera, to make it works without an Internet connection, and as I said before, it is working using its own program.

无需将相机或计算机连接到互联网即可实现此功能。当然,您可以使用互联网来完成,但是如果您的相机连接在计算机的同一网络中,或者直接通过以太网电缆连接而不使用交换机或路由器,则只需更改您的 IP 地址就足够了计算机或摄像机的 IP 地址,使它们在同一网络中工作(在计算机的情况下,使用静态 IP)。例如:

IP地址电脑:192.168.0.2 IP地址摄像机:192.168.0.3

您可以使用相机制造商提供的软件在其设置中更改相机的 IP 地址,也可以通过转到 PC 的网络和共享中心更改计算机的 IP 地址。

关于下一个问题:

To finish, if it is possible, could someone tell me what means that

../img/video.sav

上面已经回答了,我解释说这条线是制造商提供的 url 的一部分。

关于我在这里问的:

I went there and I have seen the projects he suggest to see, and I have found in the Samples directory, a project called Player, which use this method to open the url of a camera to display what is it watching:

我最终不需要它,但是如果有人拥有不止一台相机,那里显示的代码可能会有用,所以使用这个 url:

"http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=4",
"http://195.243.185.195/axis-cgi/mjpg/video.cgi?camera=3"

这部分:

?camera=3

您将指定要使用的相机。字符串的其余部分,是制造商提供的url。

我希望这对某人有所帮助,我已经花了很多时间在这上面,我很自豪能得到它,所以如果有人有任何问题,而且我可能有用,请不要犹豫,在这方面问我线程或通过直接消息。

谢谢大家!