问题描述
小弟我用c#做kinect开发,最近在写一个提取深度信息的程序,但是总是得不出想要的结果,要么是出现异常,要么就是得到的结果全都一样。我为这个问题苦恼了很久了就是想不到好的解决方法。namespacekincet_rec{///<summary>///MainWindow.xaml的交互逻辑///</summary>publicpartialclassMainWindow:Window{privateKinectSensor_kinect;privatebyte[]colorPixels1,colorPixels2;List<Image<Bgr,Byte>>VideoArray1=newList<Image<Bgr,Byte>>();List<DepthImageFrame>VideoArray2=newList<DepthImageFrame>();privateWriteableBitmapcolorBitmap,depthBitmap;privateconstintClipmaxframenum=100;privateconstintClipminframenum=120;privateDepthImagePixel[]depthPixels;shortdepth;short[]pixelData;publicintbiaoji;publicMainWindow(){InitializeComponent();}privatevoidWindow_Loaded(objectsender,RoutedEventArgse){foreach(varpotentialSensorinKinectSensor.KinectSensors){if(potentialSensor.Status==KinectStatus.Connected){this._kinect=potentialSensor;break;}}if(null!=this._kinect){this._kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);//Turnonthedepthstreamtoreceivedepthframesthis._kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);//Allocatespacetoputthedepthpixelswe'llreceivethis.depthPixels=newDepthImagePixel[this._kinect.DepthStream.FramePixelDataLength];//Allocatespacetoputthecolorpixelswe'llcreatethis.colorPixels1=newbyte[this._kinect.DepthStream.FramePixelDataLength*sizeof(int)];//Allocatespacetoputthecolorpixelswe'llreceivethis.colorPixels2=newbyte[this._kinect.ColorStream.FramePixelDataLength];//Thisisthebitmapwe'lldisplayon-screenthis.colorBitmap=newWriteableBitmap(this._kinect.ColorStream.FrameWidth,this._kinect.ColorStream.FrameHeight,96.0,96.0,PixelFormats.Bgr32,null);this.depthBitmap=newWriteableBitmap(this._kinect.DepthStream.FrameWidth,this._kinect.DepthStream.FrameHeight,96.0,96.0,PixelFormats.Bgr32,null);//Settheimagewedisplaytopointtothebitmapwherewe'llputtheimagedatathis.ColorImageWindow.Source=this.colorBitmap;this.DepthImageWindow.Source=this.depthBitmap;//Addaneventhandlertobecalledwheneverthereisnewdepthframedatathis._kinect.DepthFrameReady+=this._kinect_DepthFrameReady;this._kinect.ColorFrameReady+=this._kinect_ColorFrameReady;//Startthesensor!try{this._kinect.Start();}catch(IOException){this._kinect=null;}}}privatevoidWindowClosing(objectsender,System.ComponentModel.CancelEventArgse){if(null!=this._kinect){this._kinect.Stop();}}privatevoid_kinect_ColorFrameReady(objectsender,ColorImageFrameReadyEventArgse){using(ColorImageFramecolorFrame=e.OpenColorImageFrame()){if(colorFrame!=null){//CopythepixeldatafromtheimagetoatemporaryarraycolorFrame.CopyPixelDataTo(this.colorPixels2);//VideoArray1.Add(colorFrame.ToOpenCVImage<Bgr,Byte>());//Writethepixeldataintoourbitmapthis.colorBitmap.WritePixels(newInt32Rect(0,0,this.colorBitmap.PixelWidth,this.colorBitmap.PixelHeight),this.colorPixels2,this.colorBitmap.PixelWidth*sizeof(int),0);}}}privatevoid_kinect_DepthFrameReady(objectsender,DepthImageFrameReadyEventArgse){using(DepthImageFrameDFrame=e.OpenDepthImageFrame()){if(DFrame!=null){DFrame.CopyDepthImagePixelDataTo(this.depthPixels);intminDepth=DFrame.MinDepth;intmaxDepth=DFrame.MaxDepth;this.pixelData=newshort[_kinect.DepthStream.FramePixelDataLength];DFrame.CopyPixelDataTo(pixelData);intcolorPixelIndex=0;VideoArray2.Add(DFrame);for(inti=0;i<this.depthPixels.Length;i++){depth=depthPixels[i].Depth;byteintensity=(byte)(depth>=minDepth&&depth<=maxDepth?depth:0);//Writeoutbluebytethis.colorPixels1[colorPixelIndex++]=intensity;//Writeoutgreenbytethis.colorPixels1[colorPixelIndex++]=intensity;//Writeoutredbytethis.colorPixels1[colorPixelIndex++]=intensity;++colorPixelIndex;}this.depthBitmap.WritePixels(newInt32Rect(0,0,this.depthBitmap.PixelWidth,this.depthBitmap.PixelHeight),this.depthPixels,this.depthBitmap.PixelWidth*sizeof(int),0);}}}privatevoidColorImage_ImageFailed(objectsender,ExceptionRoutedEventArgse){}privatevoidDepthImage_ImageFailed(objectsender,ExceptionRoutedEventArgse){}privatevoidrecbtn_Click(objectsender,RoutedEventArgse){StringBuildersb=newStringBuilder();stringmyprint="";foreach(vardframeinVideoArray2){short[]pixelData=newshort[_kinect.DepthStream.FramePixelDataLength];dframe.CopyPixelDataTo(pixelData);for(inti=0;i<pixelData.Length;i+=dframe.BytesPerPixel){//myprint=depthPixels[i].Depth.ToString()+"";vardepth=pixelData[i]>>DepthImageFrame.PlayerIndexBitmaskWidth;myprint=depth.ToString()+"";sb.AppendFormat(myprint);sb.AppendFormat("nr");}for(inti=0;i<this.depthPixels.Length;i++){//depth=depthPixels[i].Depth;myprint=depthPixels[i].Depth.ToString()+"";//myprint=depth.ToString();sb.AppendFormat(myprint);sb.AppendFormat("nr");}FileStreamfs=newFileStream("E:/workspace/data"+biaoji.ToString()+".txt",FileMode.Create);StreamWritersw=newStreamWriter(fs,Encoding.GetEncoding("GB2312"));sw.Write(sb.ToString());sb.Clear();sw.Close();fs.Close();biaoji++;}}}}
我说明一下,我用一个集合videoarray2来保存从摄像头读取的每一帧图像,然后在recbtn_Click里面对每一帧的每一个像素都保存到数组pixelData里面,然后测得数组中每一个像素点的深度值,可是程序总是在执行到dframe.CopyPixelDataTo(pixelData)这里报出异常:无法访问已释放的对象异常DepthImageFrame,如果不在recbtn_Click里面保存数组pixelData,而在打开深度信息流的时候保存,则不会报异常,但是得到的全是一样的结果,这是什么原因呢?我知道坛里里面牛人很多,求大家帮帮忙,分不是很多。谢谢!
解决方案
解决方案二:
不该使用using的不要滥用它。比如说你写using(a=....){......list.Add(a);}
这种代码,你把一个执行过a.dispost()的对象放到list里,后果肯定很惨。
解决方案三:
引用1楼sp1234的回复:
不该使用using的不要滥用它。比如说你写using(a=....){......list.Add(a);}这种代码,你把一个执行过a.dispost()的对象放到list里,后果肯定很惨。
但是我录制彩色视频的时候,也是将videoarray1.add(a)写在using里面,为什么不会释放掉?
解决方案四:
videoarray1是在using中实例化的吗?如果不是当然不会释放
解决方案五:
把_kinect_DepthFrameReady方法里的using(DepthImageFrameDFrame=e.OpenDepthImageFrame())改成DepthImageFrameDFrame=e.OpenDepthImageFrame();
解决方案六:
你把using去掉试试,我也认为是using的问题,出了using作用域DFrame就被释放掉了
解决方案七:
同1楼,不理解using是什么,不要乱用.先整明白using()是起什么作用的