OpenCV:如何从以太网相机捕获帧

gpu*_*guy 8 c++ opencv ethernet ip-camera

我之前编写过USB网络摄像头,其唯一目的是从摄像头获取实时帧并在窗口中显示.我为此目的使用了cvCaptureFromCAM,它适用于USB Camera(见下面的代码).

我想知道如何从千兆以太网相机中捕获帧?我想我需要使用一些API从一些默认IP地址捕获帧.有人能指出我正确的方向吗?

我将在Intel i3处理器上的Windows 7上使用C++和OpenCV.

#include "cv.h"
#include "highgui.h"
#include <stdio.h>

// A Simple Camera Capture Framework 
int main() {
    CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
    if ( !capture ) {
        fprintf( stderr, "ERROR: capture is NULL \n" );
        getchar();
        return -1;
    }

    // Create a window in which the captured images will be presented
    cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );

    // Show the image captured from the camera in the window and repeat
    while ( 1 ) {
        // Get one frame
        IplImage* frame = cvQueryFrame( capture );

        if ( !frame ) {
            fprintf( stderr, "ERROR: frame is null...\n" );
            getchar();
            break;
        }

        cvShowImage( "mywindow", frame );

        // Do not release the frame!
        // If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
        // remove higher bits using AND operator
        if ( (cvWaitKey(10) & 255) == 27 ) break;
    }

    // Release the capture device housekeeping
    cvReleaseCapture( &capture );
    cvDestroyWindow( "mywindow" );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新

所以现在我能够在供应商提供的软件GUI中显示实时图像.但我仍然希望使用相机的IP地址显示图像(可能还有视频).

当我知道摄像机的IP地址时,为什么我无法访问摄像机发送的数据(图像)并在浏览器上显示?我尝试在我的浏览器(192.169.2.4)上键入相机的IP地址(即192.169.2.3),但它说"找不到页面".这是什么意思?

mar*_*jay 8

您可以使用genIcam API执行此操作.genIcam是相机的通用接口(USB,GigE,CameraLink等).它由多个模块组成,但您最关心的是GenTL(传输层).您可以在此处阅读有关GenTL文档的更多信息.为了简化这个过程,我建议使用Basler API或Baumer API,它们是GenTL消费者(生成者和消费者在GenTL文档中有描述).我使用了堡盟API,但两者都有效.

注意:我正在使用堡盟HXG20单声道相机.

可以下载和安装的东西

  1. Visual Studios社区版(我使用2015 LINK)
  2. 堡盟GAPI SDK,LINK
  3. openCV(这是一个为c ++构建openCV 3的youtube教程)HERE

带摄像头探测器的测试摄像机

最好通过使用Camera Explorer程序检查您的网络接口卡(NIC)和GigE相机是否正常工作并使用相机.您可能需要在NIC上启用Jumbo Packets.您也可以使用IPconfig程序配置摄像机IP.我使用DHCP设置,但您也可以为相机和NIC使用静态IP.

设置可视化工作室

有关设置系统环境变量和配置Visual Studio的步骤,请参阅Baumer GAPI SDK程序员指南(第4章),该指南位于以下目录中

C:\Program Files\Baumer\Baumer GAPI SDK\Docs\Programmers_Guide

  • 检查您是否具有以下系统变量(如果使用64位版本),或者根据需要创建变量(请参阅程序员指南中的第4.3.1节).

    • name = GENICAM_GENTL64_PATH
    • 值= C:\Program Files\Baumer\Baumer GAPI SDK\Components\Bin\x64\
  • 在visual Studios中,创建一个新的C++项目并更新以下属性(请参阅程序员指南中的第4.4.1节).

    • C/C++>常规>附加包含目录= C:\Program Files\Baumer\Baumer GAPI SDK\Components\Dev\C++\Inc
    • 链接器>常规>其他库目录= C:\Program Files\Baumer\Baumer GAPI SDK\Components\Dev\C++\Lib\x64
    • 链接器>输入>附加依赖关系= bgapi2_genicam.lib
    • 构建事件>构建后事件>命令行= copy "C:\Program Files\Baumer\Baumer GAPI SDK\Components\Bin\x64"\*.* .\

创建.CPP文件以在OPENCV窗口中显示图像流

最简单的入门方法是使用堡盟GAPI SDK中提供的示例代码之一并对其进行修改以添加openCV功能.要使用的示例代码是005_PixelTransformation,它位于此处

C:\Program Files\Baumer\Baumer GAPI SDK\Components\Examples\C++\src\0_Common\005_PixelTransformation

将此.cpp文件复制并粘贴到项目源目录中,并确保可以构建和编译.它应该捕获8个图像,并从每个图像的前6行打印出前6个像素值.

将这些#include语句添加到.cpp源文件中:

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\video\video.hpp>
Run Code Online (Sandbox Code Playgroud)

main()函数的开头添加这些变量声明

// OPENCV VARIABLE DECLARATIONS
cv::VideoWriter cvVideoCreator;                 // Create OpenCV video creator
cv::Mat openCvImage;                            // create an OpenCV image
cv::String videoFileName = "openCvVideo.avi";   // Define video filename
cv::Size frameSize = cv::Size(2048, 1088);      // Define video frame size (frame width x height)
cvVideoCreator.open(videoFileName, CV_FOURCC('D', 'I', 'V', 'X'), 20, frameSize, true); // set the codec type and frame rate
Run Code Online (Sandbox Code Playgroud)

在原始的005_PixelTransformation.cpp文件中,第569行有一个for循环,循环超过8个图像,这表示for(int i = 0; i < 8; i++).我们想要改变它以持续运行.我通过将其更改为while循环来实现此目的

while (pDataStream->GetIsGrabbing())
Run Code Online (Sandbox Code Playgroud)

在我们的新while循环中,有一个if声明可以检查Pixel格式是"Mono"(灰度)还是颜色.在原来的文件时,它开始于线619并直接在后692结束if,并else声明括号关闭,之前pImage->Release();声明,我们需要添加OpenCV的部分,显示图像的窗口.添加以下代码行

}   // This is the closing brace for the 'else color' statement 

// OPEN CV STUFF
openCvImage = cv::Mat(pTransformImage->GetHeight(), pTransformImage->GetWidth(), CV_8U, (int *)pTransformImage->GetBuffer());

// create OpenCV window ----
cv::namedWindow("OpenCV window: Cam", CV_WINDOW_NORMAL);

//display the current image in the window ----
cv::imshow("OpenCV window : Cam", openCvImage);
cv::waitKey(1);
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是openCvImage对象中的像素格式.我的相机是单声道8位,所以我需要指定CV_8U.如果您的相机是RGB或10位像素,则需要提供正确的格式(请参阅此处的openCV文档).

您可以参考其他示例来调整相机参数.

现在,一旦你构建和编译,你应该打开一个openCV窗口,显示相机图像!

为了更多人的投票而大吵大闹!!!! (这需要花很多时间才能开始工作,所以请联系我!)

为更多的投票赢得了大家!!!!!


Bul*_*ull 3

如果相机没有运行网络服务器,您将无法访问相机上的图像(检查其 doco)。尝试在命令提示符下键入:

telnet 192.169.2.3 80
Run Code Online (Sandbox Code Playgroud)

如果 telnet 超时,则说明您的摄像机未在默认端口 80 上运行服务器。

另请参阅这个问题:C++ code Capturing image from IP / Ethernet Cameras (AXIS Cam)