c# - Save depth and color streams of Kinect for Windows v2 as image files(e.g. png or jpg) -


i trying write application saves depth , color streams of kinect windows v2 image files (like png or jpg). so, used kinect sdk v2 examples(since have no prior experience c# or kinect api). modified colorbasics-wpf sample code achieve goal. here code convert color stream png files(the part modified reader_colorframearrived function):

//------------------------------------------------------------------------------ // <copyright file="mainwindow.xaml.cs" company="microsoft"> //     copyright (c) microsoft corporation.  rights reserved. // </copyright> //------------------------------------------------------------------------------ namespace microsoft.samples.kinect.colorbasics {     using system;     using system.componentmodel;     using system.diagnostics;     using system.globalization;     using system.io;     using system.windows;     using system.windows.media;     using system.windows.media.imaging;     using microsoft.kinect;     using system.collections.generic;       /// <summary>     /// interaction logic mainwindow     /// </summary>     public partial class mainwindow : window, inotifypropertychanged     {         static int count = 0;          /// <summary>         /// active kinect sensor         /// </summary>         private kinectsensor kinectsensor = null;          /// <summary>         /// reader color frames         /// </summary>         private colorframereader colorframereader = null;          /// <summary>         /// bitmap display         /// </summary>         private writeablebitmap colorbitmap = null;          /// <summary>         /// current status text display         /// </summary>         private string statustext = null;          /// <summary>         /// initializes new instance of mainwindow class.         /// </summary>         public mainwindow()         {             // kinectsensor object             this.kinectsensor = kinectsensor.getdefault();              // open reader color frames             this.colorframereader = this.kinectsensor.colorframesource.openreader();              // wire handler frame arrival             this.colorframereader.framearrived += this.reader_colorframearrived;              // create colorframedescription colorframesource using bgra format             framedescription colorframedescription = this.kinectsensor.colorframesource.createframedescription(colorimageformat.bgra);              // create bitmap display             this.colorbitmap = new writeablebitmap(colorframedescription.width, colorframedescription.height, 96.0, 96.0, pixelformats.bgr32, null);              // set isavailablechanged event notifier             this.kinectsensor.isavailablechanged += this.sensor_isavailablechanged;              // open sensor             this.kinectsensor.open();              // set status text             this.statustext = this.kinectsensor.isavailable ? properties.resources.runningstatustext                                                             : properties.resources.nosensorstatustext;              // use window object view model in simple example             this.datacontext = this;              // initialize components (controls) of window             this.initializecomponent();         }          /// <summary>         /// inotifypropertychangedpropertychanged event allow window controls bind changeable data         /// </summary>         public event propertychangedeventhandler propertychanged;          /// <summary>         /// gets bitmap display         /// </summary>         public imagesource imagesource         {                         {                 return this.colorbitmap;             }         }          /// <summary>         /// gets or sets current status text display         /// </summary>         public string statustext         {                         {                 return this.statustext;             }              set             {                 if (this.statustext != value)                 {                     this.statustext = value;                      // notify bound elements text has changed                     if (this.propertychanged != null)                     {                         this.propertychanged(this, new propertychangedeventargs("statustext"));                     }                 }             }         }          /// <summary>         /// execute shutdown tasks         /// </summary>         /// <param name="sender">object sending event</param>         /// <param name="e">event arguments</param>         private void mainwindow_closing(object sender, canceleventargs e)         {             if (this.colorframereader != null)             {                 // colorframereder idisposable                 this.colorframereader.dispose();                 this.colorframereader = null;             }              if (this.kinectsensor != null)             {                 this.kinectsensor.close();                 this.kinectsensor = null;             }         }          /// <summary>         /// handles user clicking on screenshot button         /// </summary>         /// <param name="sender">object sending event</param>         /// <param name="e">event arguments</param>         private void screenshotbutton_click(object sender, routedeventargs e)         {             if (this.colorbitmap != null)             {                 // create png bitmap encoder knows how save .png file                 bitmapencoder encoder = new pngbitmapencoder();                  // create frame writable bitmap , add encoder                 encoder.frames.add(bitmapframe.create(this.colorbitmap));                 //bitmaps.add(bitmapframe.create(this.colorbitmap.clone()));                  string time = count.tostring();                 //string time = system.datetime.now.tostring("hh'-'mm'-'ss", cultureinfo.currentuiculture.datetimeformat);                  string myphotos = environment.getfolderpath(environment.specialfolder.mypictures);                  string path = path.combine(myphotos, "kinectscreenshot-color-" + time + ".png");                  count++;                 // write new file disk                 try                 {                     // filestream idisposable                     using (filestream fs = new filestream(path, filemode.create))                     {                         encoder.save(fs);                     }                      this.statustext = string.format(properties.resources.savedscreenshotstatustextformat, path);                 }                 catch (ioexception)                 {                     this.statustext = string.format(properties.resources.failedscreenshotstatustextformat, path);                 }             }         }          /// <summary>         /// handles color frame data arriving sensor         /// </summary>         /// <param name="sender">object sending event</param>         /// <param name="e">event arguments</param>         private void reader_colorframearrived(object sender, colorframearrivedeventargs e)         {             // colorframe idisposable             using (colorframe colorframe = e.framereference.acquireframe())             {                 if (colorframe != null)                 {                     framedescription colorframedescription = colorframe.framedescription;                      using (kinectbuffer colorbuffer = colorframe.lockrawimagebuffer())                     {                         this.colorbitmap.lock();                          // verify data , write new color frame data display bitmap                         if ((colorframedescription.width == this.colorbitmap.pixelwidth) && (colorframedescription.height == this.colorbitmap.pixelheight))                         {                             colorframe.copyconvertedframedatatointptr(                                 this.colorbitmap.backbuffer,                                 (uint)(colorframedescription.width * colorframedescription.height * 4),                                 colorimageformat.bgra);                              this.colorbitmap.adddirtyrect(new int32rect(0, 0, this.colorbitmap.pixelwidth, this.colorbitmap.pixelheight));                         }                          this.colorbitmap.unlock();                     }                 }                  // modification : save current frame png file.                  if (this.colorbitmap != null)                 {                     // create png bitmap encoder knows how save .png file                     bitmapencoder encoder = new pngbitmapencoder();                      // create frame writable bitmap , add encoder                     encoder.frames.add(bitmapframe.create(this.colorbitmap));                      string time = count.tostring();                     //string time = system.datetime.now.tostring("hh'-'mm'-'ss", cultureinfo.currentuiculture.datetimeformat);                      string myphotos = environment.getfolderpath(environment.specialfolder.mypictures);                      string path = path.combine(myphotos, "kinectscreenshot-color-" + time + ".png");                      count++;                     // write new file disk                     try                     {                         // filestream idisposable                         using (filestream fs = new filestream(path, filemode.create))                         {                             encoder.save(fs);                         }                          this.statustext = string.format(properties.resources.savedscreenshotstatustextformat, path);                     }                     catch (ioexception)                     {                         this.statustext = string.format(properties.resources.failedscreenshotstatustextformat, path);                     }                 }             }         }          /// <summary>         /// handles event sensor becomes unavailable (e.g. paused, closed, unplugged).         /// </summary>         /// <param name="sender">object sending event</param>         /// <param name="e">event arguments</param>         private void sensor_isavailablechanged(object sender, isavailablechangedeventargs e)         {             // on failure, set status text             this.statustext = this.kinectsensor.isavailable ? properties.resources.runningstatustext                                                             : properties.resources.sensornotavailablestatustext;         }     } } 

the problem code generates 200 png files during recording time starting frame 90 end, frames identical each other(it starts recording run , stops whenever close it).

1) me understand why happens? why doesn't record rest of frames , repeats frame again , again?

2) have advice or pointer how can record depth , color streams image files simultaneously in efficient way , frame rate(say 20-30 fps) using kinect windows v2?

writing simultaneously color , depth streams same fps without loosing frames little tricky. in order check problem identical frames suggest try write color , depth images separate buffers (you can keep frame timestamp in buffer too) , write them disk after recording over. i'll give example , can ajust problem.

saving color frames buffer:

private void mykinectsensor_colorframeready(object sender, colorimageframereadyeventargs e)     {         using (colorimageframe color = e.opencolorimageframe())         {             if (color != null)             {                 colorbits = new byte[color.pixeldatalength];                 color.copypixeldatato(colorbits);                 image1.source = bitmapsource.create(color.width, color.height, 96, 96, pixelformats.bgr32, null, colorbits, color.width * color.bytesperpixel);                 if (startsavingframes)                 {                     savecolortimestamps.addlast(datetime.now.tostring("hhmmssfff"));                     savecolorframes.addlast(colorbits);                 }             }         }     } 

saving depth frames buffer:

private void mykinectsensor_depthframeready(object sender, depthimageframereadyeventargs e)     {         using (depthimageframe depth = e.opendepthimageframe())         {             depthpixels = new depthimagepixel[mykinectsensor.depthstream.framepixeldatalength];             if (depth != null)             {                 frame = new short[depth.pixeldatalength];                 depth.copypixeldatato(frame);                 (int = 0; < frame.length; i++)                 {                     frame[i] = (short)(((ushort)frame[i]) >> 3);                 }                 image3.source = bitmapsource.create(depth.width, depth.height, 96, 96, pixelformats.gray16, null, frame, depth.width * depth.bytesperpixel);                 if (startsavingframes)                 {                     savedepthtimestamps.addlast(datetime.now.tostring("hhmmssfff"));                     savedepthframes.addlast(frame);                 }             }         }     } 

finally, loop in each buffer , write frames disk:

            e = savecolortimestamps.getenumerator();             foreach (byte[] node in savecolorframes)             {                 e.movenext();                 pngbitmapencoder enc = new pngbitmapencoder();                 enc.frames.add(bitmapframe.create(bitmapsource.create(640, 480, 96, 96, pixelformats.bgr32, null, node, 640*4)));                 string temppath = system.io.path.combine(@"../output/kinect1/color/", e.current + ".png");                 using (filestream fs = new filestream(temppath, filemode.create))                 {                     enc.save(fs);                     fs.close();                 }             }             savecolortimestamps.clear();             savecolorframes.clear();              e.dispose();             e = savedepthtimestamps.getenumerator();             foreach (short[] node in savedepthframes)             {                 e.movenext();                 pngbitmapencoder enc = new pngbitmapencoder();                 enc.frames.add(bitmapframe.create(bitmapsource.create(640, 480, 96, 96, pixelformats.gray16, null, node, 640 * 2)));                 string temppath = system.io.path.combine(@"../output/kinect1/depth/", e.current + ".png");                 using (filestream fs = new filestream(temppath, filemode.create))                 {                     enc.save(fs);                     fs.close();                 }             } 

it not optimal way it, understand how frame-writing works , not have drop-frames.


Comments