OpenCV的:如何从一个以太网相机捕捉帧(OpenCV: How to capture frame

2019-06-25 10:40发布

我刚才已编程的USB摄像头,其中的唯一目的是让相机和显示屏实时帧的窗口。 我用cvCaptureFromCAM为目的,这工作得很好的USB摄像头(见下面的代码)。

我想知道如何从一个千兆以太网相机捕捉帧? 我想我需要捕获使用一些API从一些默认的IP地址的数据帧。 有人点我可以向正确的方向?

我将使用C ++与在Intel i3处理器在Windows 7上的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;
}

更新

所以,现在我可以显示供应商提供的软件GUI的实时图像。 但我仍想使用摄像机的IP地址显示图像(以及可能的视频)。

当我知道摄像机的IP地址,为什么我不能访问由摄像机和显示器上浏览器发送的数据(图像)? 我试着键入相机(即192.169.2.3)在我的浏览器(192.169.2.4)的IP地址,但它说“找不到网页”。 这是什么意思?

Answer 1:

您可以通过使用GenICam标准API做到这一点。 GenICam标准是相机的通用接口(USB,千兆以太网,CameraLink的,等等)。 它由多个模块组成,但你最关心的是什么GenTL(传输层)。 你可以阅读更多关于GenTL文档这里 。 为了简化这个过程,我建议您使用的巴斯勒API或堡盟的API,它是GenTL消费者(生产者和消费者的GenTL文档中描述)。 我用了堡盟API,但双方会工作。

注:我使用的是堡盟HXG20单相机。

事情要下载和安装

  1. 视觉工作室社区eddition(我用2015年LINK )
  2. 堡盟GAPI SDK, LINK
  3. OPENCV(这里是一个YouTube教程构建用于C ++的OpenCV 3) 这里

随着照相EXPLORER检验摄像机

这是一个好主意,检查您的网络接口卡(NIC)和千兆以太网相机的工作,通过相机上的资源管理器程序玩弄相机。 您可能需要启用你的网卡大型数据包。 您可以配置使用ipconfig程序以及摄像机的IP。 我用的是DHCP设置,但你也可以使用一个静态IP为您的相机和网卡。

SETUP视觉工作室

设置您的系统环境变量和配置视觉工作室的步骤在堡盟GAPI SDK编程指南介绍(第4章),它位于以下目录

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

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

    • 名称= GENICAM_GENTL64_PATH
    • 值= C:\Program Files\Baumer\Baumer GAPI SDK\Components\Bin\x64\
  • 在视觉工作室,创建一个新的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 WINDOW

上手最简单的方法是使用在堡盟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>

在开始时添加这些变量声明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

在原始文件005_PixelTransformation.cpp,线569具有for循环,循环通过8个图像,它说for(int i = 0; i < 8; i++) 我们想改变这种连续运行。 我被它改变到这样做while循环,说

while (pDataStream->GetIsGrabbing())

在我们新的while循环,有一个if语句来检查,如果像素格式是“单”(灰度)或颜色。 在原来的文件时,它开始于行619和后直接在692结束ifelse语句括号闭合,前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);

有一点要注意的是在像素格式openCvImage对象。 我的相机是一个单声道8位,所以我需要指定CV_8U 。 如果你的相机是RGB或10位像素,您需要提供正确的格式(见OpenCV的文档HERE )。

你可以参考调整相机参数的其他例子。

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

砰砰UP FOR MORE选票PEOPLE !!!! (这花了很多的时间去工作,所以钩我!)



Answer 2:

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

telnet 192.169.2.3 80

如果远程登录超时,你的相机没有运行在默认端口80上的服务器。

还看到这样的问题: C ++代码捕获来自IP /以太网摄像机图像(AXIS凸轮)



Answer 3:

要添加到纪念周杰伦的答案(我可以确认使用堡盟GAPI2 2.8.1和VC10编译器和堡盟TXG06相机一个Win32程序内的Win7x64作品)。 如果相机设置了抢Mono8和你正打算抢相同格式的图像CV_8UC1 ,然后在005_PixelTransformation.cpp例如,你可以避开创建BGAPI2::Image* pTransformImageBGAPI2::Image* pImage共和刚刚建立的cv::Mat使用缓冲内存指针从我以下摘录GigE_cam类:

bool GigE_cam::operator>>(cv::Mat& out_mat)
{
    bool success(false);
    try
    {
        _p_buffer_filled = _p_data_stream->GetFilledBuffer(static_cast<bo_uint64>(_timeout_ms));
        if(_p_buffer_filled != 0)
        {
            if(_p_buffer_filled->GetIsIncomplete())
            {
                _p_buffer_filled->QueueBuffer();
            }
            else
            {
                if(_p_buffer_filled->GetPixelFormat() == "Mono8")
                {
                    _image_out_buffer = cv::Mat(static_cast<int>(_p_buffer_filled->GetHeight()), 
                                                static_cast<int>(_p_buffer_filled->GetWidth()), 
                                                CV_8UC1, 
                                                static_cast<uchar*>(_p_buffer_filled->GetMemPtr()));
                    if(_image_out_buffer.data)
                    {
                        _image_out_buffer.copyTo(out_mat);
                        success = true;
                    }
                }
                else if(_p_buffer_filled->GetPixelFormat() == "Mono10")
                {
                    // Todo transform to BGR8 etc. not implemented
                }
                _p_buffer_filled->QueueBuffer(); // Queue buffer after use
            }
        }   
    }
    catch(BGAPI2::Exceptions::IException& ex)
    {
        _last_BGAPI2_error_str = ex.GetType();
    }
    return success;
}

在66.5 fps的,甚至在数据表仅声称64.0 FPS这个代码是越来越从摄像机(776 X 582像素)全帧。 我很好奇,看看他们的API将采取同样在Debian。



文章来源: OpenCV: How to capture frames from an Ethernet camera