c# - How to save save high frame rate camera images with live preview -
i have 2 high speed usb3 cameras (ximea) , want code application image recording. framerates 500fps @ vga resolution want use 2mpx resolution @ 170fps. .net sdk tells me should "get" images in loop. problem have no idea how images , save them while still showing live preview. everytime add code update picturebox frame rate drops drastically.
at moment utilize recording function called
task.run(() => record());
and inside record() have loop getting bitmaps
while(record == true) { camera.getimage(out myimage, timeout); //from ximea .net sdk info = camera.getlastimageparams(); timestamp = info.gettimestamp(); threadpool.queueuserworkitem(state => saveimage(myimage, filepath, timestamp)); }
with saveimage being
private void saveimage(bitmap myimage, string filepath, double timestamp) { try { lock(myimage) { myimage.save(filepath + timestamp.tostring("0.00000") + ".tif"); } } catch{} }
how can show live preview while recording , how can make entire code more stable (at moment there dropped frames because of "object in use"-errors or "generic error in gdi+" @ image.save() call, skip try/catch statement)?
i believe can tell ximea api how many image buffers want in incoming queue... use xi_prm_buffer_policy , xi_prm_buffers_queue_size appropriately make queue length long. then, have thread that, when activated, copies image out of xi_img struct own buffer. activate thread every n frames (based on size of ximea image buffer queue size)... don't memory copies in loop calls xigetimage. should block in thread avoid tearing (because ximea code around using same buffer again if you're not fast enough @ copying data out)... dynamically adjust number of buffers can finish copy within time have. also, may consider copying image data buffer if you're doing takes long time...
pseudo-code (sorry, it's c-ish):
// sync objects , global image buffer pointer critical_section cs; void *buf; handle ev; int copyimagethreadproc(...) { while (true) { if (waitonsingleobject(ev) == wait_obj_0) { entercriticalsection(cs); // copy image data @ buf ever want leavecriticalsection(cs); } } } int main(...) { // set ximea api appropriate buffering // create event , critsec, start thread while (!done) { xi_img img; xigetimage(dev, 10, &img); // every 15 frames, tell thread go... // if find critsec causing hiccup, can adjust // remember adjust queue length, // if change try entercriticalsection, can determine if ((img.acq_nframe % 15) == 0) { entercriticalsection(cs); buf = img.bp; setevent(ev); leavecriticalsection(cs); } } // clean }
Comments
Post a Comment