我正在尝试使用Egmu Open CV库使用以下代码从Kinect深度图像中提取背景:
private short[] _depthPixels;
private void OnDepthStreamReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
{
if (depthImageFrame == null) return;
depthImageFrame.CopyPixelDataTo(_depthPixels);
var displaySource = BitmapSource.Create(
640,
480,
96, 96,
PixelFormats.Gray16,
null,
_depthPixels,
640 * depthImageFrame.BytesPerPixel);
DepthImage.Source = displaySource;
var bitmap = ToBitmap(_depthPixels, 640, 480, PixelFormat.Format16bppGrayScale);
var emguImage = new Image<Gray, short>(bitmap);
}
}
private Bitmap ToBitmap( short[] pixels, int width, int height, PixelFormat format)
{
if (pixels == null)
return null;
var bitmap = new Bitmap(width, height, format);
var data = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
bitmap.PixelFormat);
Marshal.Copy(pixels, 0, data.Scan0, pixels.Length);
bitmap.UnlockBits(data);
return bitmap;
}
我想显示两个视频流:一个是来自Kinect的图像在DepthImage
上,另一个是经过处理的帧与提取的背景在第二个图像上。当我尝试创建
var emguImage = new Image<Gray, short>(bitmap);
我得到ArgumentException: "Parameter is not valid."
,和StackTrace:
at System.Drawing.Bitmap.GetPixel(Int32 x, Int32 y)
at Emgu.CV.Image`2.set_Bitmap(Bitmap value)
at Emgu.CV.Image`2..ctor(Bitmap bmp)
at Application.MainWindow.OnDepthStreamReady(Object sender, DepthImageFrameReadyEventArgs e) in e:privateApplicationMainWindow.xaml.cs:line 83
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run()
at Application.App.Main() in e:privateApplicationobjDebugApp.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
这个应用程序是在WPF中创建的。是什么导致了这个问题?
这个问题最初也难住了我一段时间。Format16bppGrayScale实际上并没有被微软完全实现,因此它不能工作(此外,我认为它与WinForms而不是WPF有关)。在我的情况下,我所做的工作是使用另一种格式,如Bgr565。如果你还在尝试用Emgu给它上灰色,那么它的质量就不完美了,但它已经足够好用了。
实际上我在这里问了几乎相同的问题