2017-02-01 1 views
0

Ich hole Infrarot-Frames von einer Kinect V2-Kamera. Die Rahmen werden in Form von WritableBitmap, also versuche ich es mit diesem Code zu konvertieren, die ich gemacht:Konvertieren von WriteableBitmap zu Mat für dann zeigt es in einem Fenster mit CvInvoke.Imshow?

public Mat WritableBitmapToMat(WriteableBitmap writeBmp) 
{ 
    Bitmap bmp; 
    using (MemoryStream outStream = new MemoryStream()) 
    { 
     BitmapEncoder enc = new BmpBitmapEncoder(); 
     enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp)); 
     enc.Save(outStream); 
     bmp = new Bitmap(outStream); 
    } 

    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 

    BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); 

    IntPtr data = bmpData.Scan0; 

    int step = bmpData.Stride; 

    Mat mat = new Mat(bmp.Height, bmp.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 4, data, step); 

    bmp.UnlockBits(bmpData); 

    return mat; 
} 

Ich weiß nicht, ob es ein Problem mit der Umwandlung ist, aber wenn ich versuche, das Bild zu zeigen, in einem Fenster mit diesem Code:

CvInvoke.Imshow("window showing a picture", infraredMat); 

ich eine Ausnahme am Ende immer die wie folgt aussieht:

Ausnahme: Exception geworfen: 'System.AccessViolationException' in Emgu.CV.World.dll ("Versuchte um geschützten Speicher zu lesen oder zu schreiben Dies ist oft ein Hinweis darauf, dass anderer Speicher c ist orrupt. ").

Ich möchte auch erwähnen, ich bin mit EmguCV 3.1 und Kinect SDK 2.0

Vielen Dank im Voraus für jede Hilfe, die ich bekommen.

+0

Haben Sie versucht, unsicheren Code/Methode zu verwenden? Da Sie direkt auf die Speicherbits zugreifen, könnte dies ein Problem darstellen. –

+0

Ich weiß, dass das Kontrollkästchen, das besagt: "unsafe code erlauben", aktiviert ist. Sollte ich auch vor meiner Methode unsicher hinzufügen? – lolistic

+0

Ich habe versucht, vor meiner Methode unsicher hinzuzufügen. Hat leider nicht funktioniert. – lolistic

Antwort

1

Wenn Sie sich das InfraredBasics-WPF-Beispiel im Kinect 2.0 SDK ansehen, werden die IR-Bilder in einen ushort-Vektor von der FrameReference.AcquireFrame()-Methode abgerufen. Dann können Sie die IntPtr infraredBuffer.UnderlyingBuffer verwenden, um auf die Rahmendaten (in einer unsicheren Methode) zuzugreifen, um den 1-D-Vektor zu erhalten. Sie können später eine 1-D- in 2-D-Matrix bei Bedarf mit den Standard-2xfor-Schleifen konvertieren.

Auf diese Weise müssen Sie nicht auf die Daten aus dem BitmapEncoder zugreifen. Da es im SDK als Standardbeispiel angegeben ist, ist es die empfohlene Methode, um die IR-Frames zu erhalten. Darüber hinaus enthält das Beispiel auch das Verfahren zum Anzeigen der IR-Bilder; es sei denn, Sie haben eine bestimmte Methode/einen bestimmten Grund, Ihren Weg zu gehen.

+0

Vielen Dank für die Antwort! Der einzige Grund, warum ich das so machen wollte, ist, sie mit EmguCV-Befehlen analysieren zu können. Das heißt nicht, dass ich weiß, was ich tue, als ich vor etwa drei Wochen angefangen habe, über Kinect und Emgu zu lernen. – lolistic

+0

Ich habe tatsächlich nicht an EmguCV gearbeitet, aber Ihr Beitrag hat mich interessiert, es zu untersuchen :) Ich bin kein C# -Experte, aber ich denke, Sie könnten versuchen, die Daten von den AcquireFrame oder reader_FrameArrived-Methoden, die das Bild für holen Verwenden Sie in der Weiterverarbeitung. –

+0

Vielen Dank für den Vorschlag! Ich werde es versuchen. Ich werde ein Update veröffentlichen, wenn es mir gelingt, es zum Laufen zu bringen. – lolistic

0

Bitmap in C# lässt sich leicht in Mat von EMGUCV umgewandelt werden, indem die folgenden Codes:

Bitmap bmp = new Bitmap("FilePath");//Declare a Bitmap Object 
Image<Bgr, Byte> bmp_I = new Image<Bgr, byte>(bmp);//Creating an Image object in EMGUCV which can read Bitmap object. 
Mat converted_mat = bmp_I.Mat;//Convert Image object into Mat 
+0

Danke für den Vorschlag, aber es ist nicht genau das, wonach ich suche. – lolistic

0

ich diese Methode mit gutem Erfolg verwendet werden:

public static Mat ToMat(BitmapSource source) 
    { 
     if (source.Format == PixelFormats.Bgra32) 
     { 
      Mat result = new Mat(); 
      result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4); 
      source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step); 
      return result; 
     } 
     else if (source.Format == PixelFormats.Bgr24) 
     { 
      Mat result = new Mat(); 
      result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 3); 
      source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step); 
      return result; 
     } 
     else if (source.Format == PixelFormats.Pbgra32) 
     { 
      Mat result = new Mat(); 
      result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4); 
      source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step); 
      return result; 
     } 
     else 
     { 
      throw new Exception(String.Format("Conversion from BitmapSource of format {0} is not supported.", source.Format)); 
     } 
    } 

Sie können diese zwicken nach Bedarf. Ich bin mir nicht sicher, ob ImShow mit einem BitMap von 32bit Floats umgehen wird. Bitmaps sind normalerweise voller Bytes. Ich könnte mich irren, aber ich habe nie versucht, etwas zu zeigen, das schwimmt.

Doug

Verwandte Themen