视觉伺服控制工具Visual Servoing Platform---VISP(1)----从相机获取图像

本文档详细介绍了如何在Unix和Windows环境下使用ViSP库从Firewire、USB摄像头以及视频流中捕获图像。示例代码展示了如何设置帧率、图像尺寸,并处理图像显示和用户交互。此外,还提到了使用OpenCV和ffmpeg进行图像和视频流的抓取。
摘要由CSDN通过智能技术生成

从firewire摄像头获取彩色图像

下面的示例演示如何在Unix下使用framegrabber从firewire摄像头获取彩色图像。
下面的示例假设libX11和libdc1394-2第三方可用。

#include <visp/vp1394TwoGrabber.h>
#include <visp/vpDisplayX.h>
#include <visp/vpImage.h>
int main()
{
#ifdef VISP_HAVE_DC1394_2
  try {
    vpImage<unsigned char> I; // Create a gray level image container
    bool reset = true; // Enable bus reset during construction (default)
    vp1394TwoGrabber g(reset); // Create a grabber based on libdc1394-2.x third party lib
    g.setVideoMode(vp1394TwoGrabber::vpVIDEO_MODE_640x480_MONO8);
    g.setFramerate(vp1394TwoGrabber::vpFRAMERATE_60);
    g.open(I);
    std::cout << "Image size: " << I.getWidth() << " " << I.getHeight() << std::endl;
#ifdef VISP_HAVE_X11
    vpDisplayX d(I);
#else
    std::cout << "No image viewer is available..." << std::endl;
#endif
    while(1) {
      g.acquire(I);
      vpDisplay::display(I);
      vpDisplay::flush(I);
      if (vpDisplay::getClick(I, false))
        break;
    }
  }
  catch(vpException e) {
    std::cout << "Catch an exception: " << e << std::endl;
  }
#endif
}

在这里,我们解释了引入的新行。

首先创建帧抓取器的实例。在创建过程中,发送总线重置。如果不想重置firewire总线,只需将reset设置为false。

vp1394TwoGrabber g(reset);

创建抓取器后,我们设置相机图像大小、颜色编码和帧速率。

g.setVideoMode(vp1394TwoGrabber::vpVIDEO_MODE_640x480_MONO8);
g.setFramerate(vp1394TwoGrabber::vpFRAMERATE_60);

请注意,这里可以指定一些其他设置,例如firewire传输速度。有关更完整的设置列表,请参阅vp1394TwoGrabber类。

g.setIsoTransmissionSpeed(vp1394TwoGrabber::vpISO_SPEED_800);

Then the grabber is initialized using:

g.open(I);

从现在起,彩色图像I也将初始化为与抓取器设置相对应的大小。
然后,我们进入一个while循环,其中图像采集只需通过以下方式完成:

g.acquire(I);

我们正在等待非阻塞鼠标事件在结束程序之前中断while循环。

if (vpDisplay::getClick(I, false)) break;

在上一个示例中,我们使用vp1394TwoGrabber类,该类在Unix下适用于firewire摄像头。如果您在Windows下,则可以使用vp1394CMUGrabber类。教程-grabber-CMU1394.cpp中提供了类似的示例。

从USB等摄像机采集图像

如果您想在Unix下从usb摄像头抓取图像,可以使用VPV4L2GRABER类。为此,应安装libv4l。教程-grabber-v4l2.cpp中提供了一个示例。

#include <visp/vpV4l2Grabber.h>
#include <visp/vpDisplayX.h>
#include <visp/vpImage.h>
int main()
{
#ifdef VISP_HAVE_V4L2
	try{
	  vpImage<unsigned char> I;
	  vpV4l2Grabber g;
	  g.open(I);
	  std::cout << "Image size: " << I.getWidth() << " " << I.getHeight() << std::endl;
#ifdef VISP_HAVE_X11
	  vpDisplayX d(I);
#else
	  std::cout << "No image viewer is available..." << std::endl;
#endif
	while(1) {
	  g.acquire(I);
	  vpDisplay::display(I);
	  vpDisplay::flush(I);
	  if (vpDisplay::getClick(I, false)) break;
	  }
	}
	catch(vpException e) {
	  std::cout << "Catch an exception: " << e << std::endl;
	  }
#endif
	}

也可以使用OpenCV抓取图像。您可以在教程grabber opencv和教程opencv-bis.cpp中找到示例添加链接描述
当然让还有其他很多方法

来自视频流的图像

使用ViSP还可以从输入视频流中获取图像。为此,我们利用ffmpeg第三方。下面的示例在教程grabber视频中提供。CPP显示了如何考虑MPEG视频流:

#include <visp/vpDisplayX.h>
#include <visp/vpVideoReader.h>
int main()
{
#ifdef VISP_HAVE_FFMPEG
  try {
    vpImage<unsigned char> I;
    vpVideoReader g;
    g.setFileName("./video.mpg");
    g.open(I);
    std::cout << "video framerate: " << g.getFramerate() << "Hz" << std::endl;
    std::cout << "video dimension: " << I.getWidth() << " " << I.getHeight() << std::endl;
#ifdef VISP_HAVE_X11
    vpDisplayX d(I);
#else
    std::cout << "No image viewer is available..." << std::endl;
#endif
    vpDisplay::setTitle(I, "Video grabber");
    while (! g.end() ) {
      double t = vpTime::measureTimeMs();
      g.acquire(I);
      vpDisplay::display(I);
      vpDisplay::flush(I);
      if (vpDisplay::getClick(I, false)) break;
      vpTime::wait(t, 1000. / g.getFramerate());
    }
  }
  catch(vpException e) {
    std::cout << "Catch an exception: " << e << std::endl;
  }
#endif
}

我们现在解释一下导入的一些库。

#include <visp/vpTime.h>
#include <visp/vpVideoReader.h>

包括允许测量时间的vpTime类的标头,以及允许读取视频流的vpVideoReader类的标头。

vpVideoReader g;

创建视频读取器的实例。

g.setFileName("./video.mpg");

设置视频流的名称。这里是视频。mpg是指与可执行文件位于同一文件夹中的mpeg文件。
vpVideoReader类还可以处理一系列图像。例如,要读取以下图像:

% ls *.png
image0000.png
image0001.png
image0002.png
image0003.png
image0004.png
...
您可以使用以下命令
```cpp
g.setFileName("./image%04d.png");

其中指定每个图像编号用4位数字编码。在这里,ffmpeg还不是强制性的,而是应该可用于读取PNG图像的libpng。支持的图像格式有PPM、PGM、PNG和JPEG。在最后一种情况下,应该安装libjpeg。
然后,对于任何其他抓取器,必须使用以下命令初始化帧抓取器:

g.open(I);

然后,我们进入while循环,直到没有到达最后一个图像:

while (! g.end() ) {

要获取流中的下一个图像,我们只需使用:

g.acquire(I);

为了使视频解码与视频帧率同步,我们测量每个循环迭代的开始时间:

double t = vpTime::measureTimeMs();

通过使用以下命令,从迭代开始等待以毫秒为单位的相应时间来完成同步:

vpTime::wait(t, 1000. / g.getFramerate());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值