我刚才已编程的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地址,但它说“找不到网页”。 这是什么意思?
您可以通过使用GenICam标准API做到这一点。 GenICam标准是相机的通用接口(USB,千兆以太网,CameraLink的,等等)。 它由多个模块组成,但你最关心的是什么GenTL(传输层)。 你可以阅读更多关于GenTL文档这里 。 为了简化这个过程,我建议您使用的巴斯勒API或堡盟的API,它是GenTL消费者(生产者和消费者的GenTL文档中描述)。 我用了堡盟API,但双方会工作。
注:我使用的是堡盟HXG20单相机。
事情要下载和安装
- 视觉工作室社区eddition(我用2015年LINK )
- 堡盟GAPI SDK, LINK
- 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
创建一个.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结束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);
有一点要注意的是在像素格式openCvImage
对象。 我的相机是一个单声道8位,所以我需要指定CV_8U
。 如果你的相机是RGB或10位像素,您需要提供正确的格式(见OpenCV的文档HERE )。
你可以参考调整相机参数的其他例子。
现在,一旦你建立和编译,你应该有一个显示相机图像的OpenCV的窗口打开!
砰砰UP FOR MORE选票PEOPLE !!!! (这花了很多的时间去工作,所以钩我!)
您将无法在相机上访问图像,如果它没有运行Web服务器(检查其DOCO)。 请尝试在命令提示符下键入如下:
telnet 192.169.2.3 80
如果远程登录超时,你的相机没有运行在默认端口80上的服务器。
还看到这样的问题: C ++代码捕获来自IP /以太网摄像机图像(AXIS凸轮)
要添加到纪念周杰伦的答案(我可以确认使用堡盟GAPI2 2.8.1和VC10编译器和堡盟TXG06相机一个Win32程序内的Win7x64作品)。 如果相机设置了抢Mono8
和你正打算抢相同格式的图像CV_8UC1
,然后在005_PixelTransformation.cpp
例如,你可以避开创建BGAPI2::Image* pTransformImage
和BGAPI2::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。