OpenCV erstellt Mat aus dem Byte-Array

9

In meiner C ++ - DLL erstelle ich Mat aus Byte-Array:

%Vor%

Das Bild wird mit einem Grauton erstellt, nicht dem Original.

Ist das die richtige Art, Mat aus dem Byte-Array zu erstellen?

Siehe Code

ptrImageData wird von C # -Code an die C ++ - DLL übergeben.

C # -Code zum Übergeben der Bilddaten

%Vor%     
user1858884 28.11.2012, 06:50
quelle

3 Antworten

1

Der C ++ - Code scheint in Ordnung zu sein, da er einen Matrix -Wrapper für die gelieferten Bilddaten erzeugt, vorausgesetzt, der Puffer ist im konventionellen RGB8-Format. Beachten Sie, dass dieser Konstruktor nicht den Puffer kopiert, sodass der Puffer für die Dauer dieser Mat -Instanz gültig bleiben muss (oder kopiert werden muss).

%Vor%

Es scheint, dass das Problem in Ihrem C # -Code liegt. Ich bin kein C # -Entwickler, aber ich werde mein Bestes geben, um zu helfen. Sie erstellen einen Speicherstream und verwenden den JPEG-Codec, um eine komprimierte Version des Bildes in den Puffer zu schreiben, als wäre es eine Datei. Aber das ist nicht das Datenformat, das cv::Mat erwartet, so dass Sie grundsätzlich Müll sehen (komprimierte Daten werden als unkomprimiert interpretiert).

Wenn Sie eine System.Image.Drawing.Image -Instanz angeben, können Sie direkt ein Wrapper Bitmap -Objekt erstellen (oder vielleicht as , da es sich um einen einfachen Downcast handelt). Dann können Sie einfach die Methode Bitmap.LockBits() verwenden, um a zu erhalten Zeiger auf die zugrunde liegenden Bilddaten.

%Vor%

und dann kannst du das rgbBuffer an OpenCV übergeben.

Ich bin nicht davon überzeugt, dass die Speicherverwaltung im ursprünglichen Code auch vollständig korrekt ist, aber obiges funktioniert, vorausgesetzt, der Umfang des Pufferbesitzes liegt innerhalb der Methodenaufrufe für Sperren und Entsperren. Wenn die Bilddaten diesen Codeblock überleben sollen, müssen Sie den Puffer kopieren.

Seien Sie auch bei Ihren Pixelformaten vorsichtig - Sie müssen sicherstellen, dass die Instanz Image/Bitmap wirklich RGB8-Daten enthält. OpenCV cv::Mat hat verschiedene Flags, so dass Sie mit einer Vielzahl von Bildformaten im Speicher arbeiten können. Beachten Sie jedoch, dass diese Dateien nicht wie die Formate auf der Festplatte (normalerweise komprimiert) wie PNG, TIFF usw. sind.

    
gavinb 28.09.2016 11:39
quelle
0

Ja, dies ist eine Möglichkeit, eine Matte aus einem Byte-Array zu erstellen. Sie müssen nur darauf achten, dass Ihr Array enthält, was Sie denken, dass es tut.

  

Das Bild wird mit einem Grauton erstellt, nicht dem Original.

Sie erhalten also ein Bild in newImg? Was war das Pixelformat der Originaldaten?

Vielleicht hast du die roten und blauen Kanäle gewechselt. Die folgende Zeile wird die Kanäle tauschen:

%Vor%     
M Miller 22.03.2013 18:23
quelle
0

Hier ist der Link zur Dokumentation: Ссылка

Im Allgemeinen solltest du zwei Dinge beachten:

  1. Wenn Sie externe Daten an den Matrixkonstruktor übergeben, werden die externen Daten nicht automatisch freigegeben. Sie sollten also darauf achten. Wenn Sie möchten, dass die OpenCV-Matrix sich um den Speicher kümmert, sollten Sie die Matrix kopieren (Sie können dies auf viele Arten tun, zB mit Mat :: Klon oder Mat :: copyTo Methoden.
  2. Externe Daten können nicht kontinuierlich sein, d. h. die Größe der Zeile kann größer als die Breite multipliziert mit der Anzahl der Kanäle multipliziert mit der Größe des Datenelements sein. Sie können also "step" als letztes Argument des Konstruktors angeben. Wenn Sie externe Daten manuell zuordnen und 100% sicher sind, dass sie fortlaufend sind, können Sie den Schritt nicht bestehen und sich auf die automatische Schrittberechnung verlassen.

Ich bin mit C # nicht vertraut, aber es scheint mir, dass Sie Daten direkt nach dem Aufruf von ProcessImage freigeben. Wenn also ProcessImage asynchron ist oder Ihre Matrix irgendwie zwischenspeichert (d. H. Die Lebensdauer der Matrix ist länger als der Aufruf von ProcessImage), sollten Sie sich um die Speicherverwaltung kümmern.

    
Vlad 24.07.2015 09:15
quelle

Tags und Links