基于Openframeworks调取摄像头方式的定时抓拍保存图像方法小结

这次是采用Openframeworks来调取摄像头画面并抓图保存。

开始

借向导自动生成代码,因为要调取摄像头设备,因此增添ofVideoGrabber对象声明,又因为保存需求,所以还需添加ofPixels对象声明。如下:

ofVideoGrabber vidGrabber;
ofPixels videoPixels;

还需添加如下变量:

float timer;  //方便计时
int framecount; //序列帧数,计数
int oldtime;  //上一帧的总流逝时刻
int nowtime;  //当前帧的总流逝时刻

oldtimenowtime是为了方便计算每帧所消耗的时间,方便计时。头文件最后的编辑如下:

#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());
}

结果

运行时的应用:
image
得到的图片序列:
image

posted @ 2021-09-26 20:41  SHARP-EYE  阅读(402)  评论(0编辑  收藏  举报