基于Openframeworks调取摄像头方式的定时抓拍保存图像方法小结
这次是采用Openframeworks来调取摄像头画面并抓图保存。
开始
借向导自动生成代码,因为要调取摄像头设备,因此增添ofVideoGrabber
对象声明,又因为保存需求,所以还需添加ofPixels
对象声明。如下:
ofVideoGrabber vidGrabber;
ofPixels videoPixels;
还需添加如下变量:
float timer; //方便计时
int framecount; //序列帧数,计数
int oldtime; //上一帧的总流逝时刻
int nowtime; //当前帧的总流逝时刻
oldtime
、nowtime
是为了方便计算每帧所消耗的时间,方便计时。头文件最后的编辑如下:
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofVideoGrabber vidGrabber;
ofPixels videoPixels;
float timer;
int framecount;
int oldtime;
int nowtime;
};
接下来
在setup()
中初始化对象,配置参数,具体写法如下:
void ofApp::setup(){
vector<ofVideoDevice> devices = vidGrabber.listDevices();
vidGrabber.setDeviceID(0);
vidGrabber.setDesiredFrameRate(60);
//vidGrabber.setPixelFormat(OF_PIXELS_RGB);
vidGrabber.initGrabber(1920,1080);
videoPixels.allocate(1920, 1080, OF_PIXELS_RGB);
ofSetVerticalSync(true);
timer = 2000.0f;
framecount = 0;
}
想设置摄像头采集图像的模式为MJPG
,但是没找到方法,尝试了几个Format但未奏效。使用它默认的YUY2
模式,高分辨率采集下其帧率水平很低,不过光抓图没有多大关系。
再者
现在的任务是每次更新采集画面,并且把画面数据转移到自己创建的对象中,并且每隔一段时间保存图像到本地磁盘。
void ofApp::update(){
vidGrabber.update(); //摄像头更新画面
nowtime = ofGetElapsedTimeMillis(); //获取当前进程流逝的时间,即当前帧的时刻
timer -= nowtime - oldtime; //每帧所消耗的时间 - deltatime
oldtime = nowtime;
if (vidGrabber.isFrameNew()) {
videoPixels = vidGrabber.getPixels(); //将摄像头实时画面信息转换到自己的图像对象中
if (timer <= 0)
{
//ofSaveImage(videoPixels, "e:\\capturefromOF\\image_" + std::to_string(framecount) + ".jpg");
char buffer[50];
snprintf(buffer, 10, "%06d", framecount); //格式化字符串 000001 000002
//ofLogNotice() << buffer;
string str(buffer);
ofSaveImage(videoPixels, "e:\\capturefromOF\\image_" + str + ".jpg"); //保存图像,命名格式如 image_######.jpg 序列
ofLogNotice() << "saved frame no." << framecount;
framecount++; //序列图的序号累计
timer = 2000.0f; //相隔两秒触发一次
}
}
//ofLogNotice() << timer;
}
最后
一些方便调试的操作。
//--------------------------------------------------------------
void ofApp::draw(){
ofSetHexColor(0xffffff);
vidGrabber.draw(20, 20, 1920 / 2, 1080 / 2);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 's' || key == 'S') {
vidGrabber.videoSettings(); //可以调节参数
}
}
当然主函数不动:
#include "ofMain.h"
#include "ofApp.h"
//========================================================================
int main( ){
ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context
ofRunApp(new ofApp());
}
结果
运行时的应用:
得到的图片序列: