下面的示例演示如何在Unix下使用framegrabber从firewire摄像头获取彩色图像。
下面的示例假设libX11和libdc1394-2第三方可用。
#include#include #include int main() { #ifdef VISP_HAVE_DC1394_2 try { vpImage 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#include #include int main() { #ifdef VISP_HAVE_V4L2 try{ vpImage 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#include int main() { #ifdef VISP_HAVE_FFMPEG try { vpImage 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#include
包括允许测量时间的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());
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)