OpenCV 入门级之USB摄像头采集[转]

前面两篇博文呢,介绍了 OpenCV
的环境搭配以及最基本的几个函数的使用,

而这一篇博文则还是延续以 Demo 讲述
OpenCV API 的方式,

因为有些 API
是用得很多的,所以必须要熟练,而至于其他的一些比较罕见的 API ,

则可以通过在 OpenCV 官网上下载必要的 API
文档来熟悉就 OK 了,

对于在前面呢,基本上介绍了 IplImage 以及
CvCapture 的使用,下面的 Demo 呢,

其实和前面差不多,只不过,我是通过摄像设备捕捉到帧后进行的处理,

其实这个并不难,有兴趣的可以在等下的 Demo
中看到,对于摄像设备的处理,

和处理普通的视频文件其实没有什么太大的区别,但是,兴趣这个东西是很神奇的,

只有兴趣浓厚,才有可能学好一门技术,而视频文件和摄像设备相比,

很显然,能够控制摄影摄像设备更让人振奋,

所以下面的 Demo
使用了摄像设备,同时可以实现拍照以及录视频的功能。

首先,我使用的环境是 VS2008 + OpenCV
2.0 ,同时,由于涉及到摄像设备,而我电脑这里没有摄像头,

所以勉强拿了个手机充当了摄像头,所以拍出来效果极差。

拍照功能

注意注释部分,其中使用的比较生疏的 API 包括 cvPyrDown 
cvCreateCameraCapture

以及 cvCopy 和 cvSaveImage

下面就来一一解释这几个 API
的具体使用:

          

void cvPyrDown( const CvArr* src, CvArr* dst,
int filter=CV_GAUSSIAN_5x5 );

其中 src 为 CvArr *
类型,这里顺便解释一下 OpenCV 基本上是用 C 实现的,当然其中包括一定的 C++ 成分,

但是 OpenCV
中仍然也使用了面向对象的思想,即有以下的继承关系:

所以在实际使用当中,完全可以使用 ”子类”
CvMat 或者是 IplImage 来代替 CvArr ,

也就是说在参数中完全可以传入一个 IplImage
类型,

src 代表的就是源图像,即传入函数的图像,而
dst 则是输出图像,即缩放一倍后的图像,

但是需要注意的是,在这里传入的 dst
图像必须是在初始化以后才能传入,

对于这一点,在下面的 Demo
中可以看到。而至于卷积滤波器的类型则一般采用默认类型即可。

CvCapture* cvCreateCameraCapture( int index
);

大伙应该还记得 cvCreateFileCapture 这个函数吗?这在笔者前面的一篇博文中有使用的,

尚不清楚的可以参考:

http://www.cnblogs.com/QinBaoBei/archive/2010/10/24/1859704.html

其实对于 cvCreateFileCapture 来说,其是根据一个指定的视频文件来初始化,

而对于 cvCreateCameraCapture 则不同,其是通过初始化一个视频设备
(也可以看做就是一个摄像头),

初始化以后,便可以从这个摄像设备中获取视频了。

至于参数 index
的话,如果您的电脑上连接了多个摄像设备,则需要通过这个  index  来指定到底要使用哪一个摄像头。

void cvCopy( const CvArr* src, CvArr* dst,
const CvArr* mask=NULL );

这个函数的作用是拷贝一个数组到另一个数组,而根据前面的继承关系,IplImage 
继承自  CvMat,

而 CvMat 又是继承于  CvArr
,所以在此处可以直接传入一个  IplImage  来实现拷贝,

很明显,src 是传入的数组,而 dst
则是复制完成后返回的结果数组,

而至于 mask
这个数组呢,比较变态,

它指定了数组 src 中那些元素需要拷贝到 dst
数组中,那些元素不能够拷贝到 dst 数组中,

mask 数组中标记为非 0 的则可以拷贝到 dst
中,标记为 0 的则不会拷贝到 dst 数组当中去。

这里需要注意的是,dst 数组和 src
数组必须是相同的类型,并且具有相同的维数和大小,否则整个程序会崩溃。

int cvSaveImage( const char* filename, const
CvArr* image );

这个函数的作用很明显,即保存图片到文件,而至于保存的图片的文件则看 
filename  这个参数指定的后缀名是什么了。

上面几个 API
的具体使用可以参见下面的 Demo :

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

//实现将拍下来的图片缩放一倍
IplImage * DoPyrDown(IplImage * image,int filter = IPL_GAUSSIAN_5x5)
{
//设置大小缩小一倍
CvSize size = cvSize(image->width / 2,image -> height / 2);

//初始化图片
IplImage * outImage = cvCreateImage(size,image->depth,image->nChannels);

//实现缩放
cvPyrDown(image,outImage);

cvReleaseImage(&image);
return outImage;
}

int main(int argc,char ** argv)
{
cvNamedWindow("Demo08");
CvCapture * capture;

//首先是要通过摄像设备来得到一个CvCapture 对象
if(argc == 1)
{
capture=cvCreateCameraCapture(0);
}
else
{
capture=cvCreateCameraCapture(atoi(argv[1]));
}
assert(capture!=NULL);

IplImage * frame;

char keyCode;
//每隔30ms 捕捉一次视频图像
while((keyCode = cvWaitKey(30)))
{
//表示按下了Esc 键
if(keyCode == 27)
{
break;
}

//表示按下了回车键,此时应当保存照片
if(keyCode == 13)
{
//初始化一张图片
IplImage * outImage = cvCreateImage(
cvGetSize(frame),
frame->depth,
frame->nChannels);
//将原图拷贝过来
cvCopy(frame,outImage,NULL);

//实现缩放操作
outImage= DoPyrDown(outImage);

char *outImageName = "XiaoZhen.jpg";

//将图片保存
cvSaveImage(outImageName,outImage);

cvReleaseImage(&outImage);

printf("恭喜你, 保存图片成功! \n");
}

//得到摄像设备中的下一帧图像
frame = cvQueryFrame(capture);

if(!frame)
{
break;
}
cvShowImage("Demo08",frame);
}

cvReleaseImage(&frame);
cvDestroyAllWindows();
return 0;
}

下面就来看看效果是什么样了:(手机差,所以效果不咋的)

当按下回车键的时候便可以实现保存图片了

由于我对从摄像头中的图片进行了缩放,所以看起来效果就更差了

好,第一个 Demo
就到此结束了,下面呢,在介绍一个 Demo ,

这个 Demo
呢,通过从摄像头读到的内容来生成一个视频文件。

制作视频功能

和第一个 Demo 一样,还是从 API
说起,

在下面的 Demo
中呢,主要是使用了以下的几个特殊点的 API ,包括  cvCreateVideoWriter 
和  cvWriteFrame 至于其他的一些 API
,在前面的博文都是有所触及的。

CvVideoWriter* cvCreateVideoWriter( const char*
filename,

                                   
int fourcc,

                                   
double fps,

                                   
CvSize frame_size,

                                   
int is_color=1 );

这个函数的作用就是初始化一个视频文件写入器,其中的参数的话,

filename 
不用多说,自然是指将要创建的视频文件的名称,

fourcc 
则代表的是视频压缩的编码格式,

CV_FOURCC(‘P‘,‘I‘,‘M‘,‘1‘)  是 MPEG-1 codec,

CV_FOURCC(‘M‘,‘J‘,‘P‘,‘G‘)  是motion-jpeg codec等。

在 Win32 下,如果传入参数 -1,可以从一个对话框中选择压缩方法和压缩参数。

fps 
则代表的是帧率。

is_color 
则代表是希望得到彩色帧还是得到灰度帧。

int cvWriteFrame( CvVideoWriter* writer, const
IplImage* image );

这个 API
的作用是非常明显的,即写一个帧到视频文件中,至于参数的话我想也不需要多做解释了。

下面就来看 Demo
了:

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

int main(int argc,char ** argv)
{
cvNamedWindow("Demo09");
CvCapture * capture = 0;

if(argc == 1)
{
capture = cvCreateCameraCapture(0);
}
else
{
capture = cvCreateCameraCapture(atoi(argv[1]));
}

if(!capture)
{
return -1;
}

IplImage * frame;
//指定视频中每一帧的大小(我的摄像头拍摄下的图片均是 160 * 120 的)
CvSize size = cvSize(160,120);
//需要初始化一个写视频文件的对象,这里注意使用的编解码器格式是 MJPG
//帧率设置为 5
CvVideoWriter * videoWriter =
cvCreateVideoWriter("BoyXiao.avi",CV_FOURCC(‘M‘,‘J‘,‘P‘,‘G‘),5,size);

char keyCode;
//每隔30ms 从摄像头中取出一帧
while(( keyCode = cvWaitKey(30)))
{
if(keyCode == 27)
{
break;
}
//得到从摄像头中获取的帧
frame = cvQueryFrame(capture);

//将帧写入视频文件中
cvWriteFrame(videoWriter,frame);

cvShowImage("Demo09",frame);
}

cvReleaseVideoWriter(&videoWriter);
cvReleaseImage(&frame);
cvDestroyWindow("Demo09");

return 0;
}

下面就来验收一下结果了:

首先自然是录制视频了。

视频录制完成后可以在项目根目录下看到创建好的视频文件

当然视频文件也是可以播放的

这一篇博文到此又结束了,其实呢,这篇博文没什么技术含量,

主要是通过使用了摄像头来摆弄视频,

想在此展现的就是一种好玩的心态,或者说是兴趣,

笔者一直都认为,只要对一个东西有了兴趣,那么接下来想搞定它那就不会太难了,

所以本篇博文纯粹本着培养兴趣的心态而作。

OpenCV 入门级之USB摄像头采集[转],布布扣,bubuko.com

时间: 2024-10-14 07:07:41

OpenCV 入门级之USB摄像头采集[转]的相关文章

基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)

基于opencv和mfc的摄像头采集框架(GOMFCTemplate2) 编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料,通过在实际项目中的积累,我总结出来一套结合opencv和mfc的摄像头采集框架.具有以下特点: 1.基于directshow,兼容性好,速度快.到目前为止,无论是工业相机还是普通相机,没发现不兼容的: 2.摄像头部分通过线程读取,保证界面的运行流畅:

基于opencv和QT的摄像头采集代码( GoQTtemplate3持续更新)

在Linux操作系统上,编写带界面的图像处理程序,选择opencv+QT是一种很好的选择.GoQTtemplate3是我为编写Linux下图像处理程序实现的框架,希望能够为大家解决Linux环境下桌面图像处理程序,提供一些帮助. 文中相关代码请参考:https://github.com/jsxyhelu/GOQTtemplate3 一.基本环境构建 a.我们需要完整地安装QT.具体方法,是从网站上下载在线安装程序,并且直接安装 b.下载并且安装OpenCV 直接使用编译好的OpenCV类库 su

linux FFMPEG 摄像头采集数据推流

Linux下用 FFMPEG 采集 usb摄像头视频 和 摄像头内置麦克风音频 到RTMP服务 ffmpeg -f video4linux2 -qscale 10 -r 12 -s 640x480 -i /dev/video0 -f alsa -i hw:1 -ab 16 -ar 22050 -ac 1 -f mp3 -f flv rtmp://127.0.0.1/rtmpsvr/rtmp1 ./ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 -

Bananapro SimpleCV &amp; usb摄像头教程

最近折腾图像处理,看重了simpleCV与python的简便,想要在Bnanapro上安装SimpleCV,于是折腾了一天才安装好,下面和大家分享一下! 提前说明!请不要完全按照网上其他树莓派安装SimpleCV的教程安装,有一些低层库Bananapro和树莓派相差很大! 1.编译安装opencv 这个早有人在论坛里分享过,我就贴个链接 http://forum.lemaker.org/cn/forum.php?mod=viewthread&tid=8894&extra=page%3D2

ROS安装USB摄像头

本文为原创,转载请注明来自CSDN Jasmine_shine的专栏 网址:http://blog.csdn.net/jasmine_shine/article/details/46715099 1.  明确USB摄像头的型号. 在终端键入$lsusb ,会显示所有的摄像头的型号编码,具体参考: http://www.ideasonboard.org/uvc/ 根据上面给出的ID我找出了蓝色妖姬t3200这款摄像头的ID号是18ec:3299      USB 2.0 PCCamera (mod

USB摄像头之130w像素 OV9655配置,ov9650,ov7725,ov7670

USB摄像头之130w像素 OV9655配置 为了usb2.0采集达到足够的速率,不得不将采用raw格式输出. // 20150411 XVGA 1280*1024 实际上位机需要2560*1024 采集 code unsigned char ov9655_sxga[150][2] = { //1280 10240x12, 0x80,0x00, 0x00,0x01, 0x80,0x02, 0x80,0x03, 0x1b,//vref0x04, 0x03,//skip def:03 0x0b, 0

USB摄像头无法正常读取问题

opencv读取摄像头或者视频一种是早期版本的IplImage结构体,图片就存在结构体指针IplImage*中,另一种是Mat类,两者在操作上略有差异,且opencv2都兼容这两个版本,前面的博客也说了两者可相互转换,工程实际中经常需要接触. 最近在读取USB摄像头时,出现闪退,核心的问题是第一帧无法读取,导致流循环被终止,根本没读到数据,这是我接触的第三个USB摄像头,有点奇怪. 解决办法是可以读入两次,即第一帧读不到,就读第二帧:也可以用continue语句继续读取而不终止循环. 原文地址:

Jetson TX2(3)opencv3 打开usb摄像头

ubuntu2604 opencv3.4.0 https://blog.csdn.net/ultimate1212/article/details/80936175?utm_source=blogxgwz7 cmake_minimum_required(VERSION 2.8) project(DisplayImage) set( CMAKE_CXX_FLAGS "-std=c++11 -O3" ) find_package( OpenCV REQUIRED ) #if(CMAKE_V

C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流

https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118312/11238555 https://github.com/wanglong/DirectShow.NET-Webcam-Barcode-Reader 开源社区提供了DirectShow的.NET版本,为C#开发者提供了便利.这里分享下如何用DirectShow.NET API来启动摄像头,以及