在今天以前,我一直认为摄像头是一个神秘的东西。怎么才能在自己的程序中读取摄像头的画面,想想都无从下手。
然而今天终于知道, 这在OpenCV中是一件多么简单的事情。仅仅调用一个函数,就能从摄像头中读取一帧帧的画面,想显示还是保存,随意。显示的话,就是实时的视频图像;保存的话,就是视频文件了。
准备工作
准备工作极为简单,找一个普通的摄像头,插到USB口中。然后点开QQ视频,确保它能正确工作。
读取摄像头
核心代码
CvCapture* capture = cvCreateCameraCapture(0); IplImage* frame = cvQueryFrame(capture);
第一行创建了一个来自摄像头的capture,注意其参数为0,表示随机取一个摄像头。当我们电脑上只有一个摄像头时,就填它。如果有多个,还需要指定设备id。
第二行是从该capture中读取下一帧画面。不断的调用第二句,就能不断得到新的画面。
示例效果
完整代码
#include "cv.h" #include "highgui.h" int main(int argc, char** argv) { cvNamedWindow("win"); CvCapture* capture = cvCreateCameraCapture(0); IplImage* frame; while(1) { frame = cvQueryFrame(capture); if(!frame) break; cvShowImage("win", frame); char c = cvWaitKey(50); if(c==27) break; } cvReleaseCapture(&capture); cvDestroyWindow("win"); return 0; }代码相当简单,但实现了读取摄像头并显示在一个屏幕窗口的功能。
对画面进行处理
从代码中可以看到,我们是以图片方式读取摄像头数据,这样就可以在显示到窗口前,对图片进行操作。想到我们在前面介绍过对图片进行寻边的操作,可以试试把它们结合在一起,得到不一样的效果。
首先看最终效果:
从视频窗口看到的效果变成了这样,是不是挺恐怖?
完整代码
代码也相当简单,即在每帧图片显示在窗口前,先对它进行一个cvCanny的操作即可。
完整代码如下:
#include "cv.h" #include "highgui.h" int main(int argc, char** argv) { cvNamedWindow("win"); CvCapture* capture = cvCreateCameraCapture(0); IplImage* frame = cvQueryFrame(capture); while(1) { frame = cvQueryFrame(capture); if(!frame) break; IplImage* out = cvCreateImage(cvGetSize(frame), frame->depth, 1); cvCanny(frame, out, 10, 100, 3); cvShowImage("win", out); cvReleaseImage(&out); char c = cvWaitKey(50); if(c==27) break; } cvReleaseCapture(&capture); cvDestroyWindow("win"); return 0; }