2012-10-02 5 views
6

Ich muss ein Bild mit OpenCV lesen, seine Größe erhalten und an einen Server senden, damit es das Bild verarbeitet und mir das extrahierte zurückgibt Eigenschaften.Speichern Sie eine cv :: Mat in einem Byte-Array für die Datenübertragung an einen Server

Ich habe gedacht, eine vector<byte> zu verwenden, aber ich verstehe nicht, wie man die Daten zu einem cv :: Mat kopiert. Ich möchte es schnell machen, also versuche ich mit einem Zeiger auf die Daten zuzugreifen, aber ich habe eine Laufzeitausnahme. Ich habe so etwas.

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i + j));    

     }   
    } 
  • Welches ist der beste Ansatz für diese Aufgabe?

Antwort

7

Direkter Zugang ist eine gute Idee, da es die schnellste für OpenCV ist, aber Sie vermissen den Schritt und das ist wahrscheinlich der Grund, warum Ihr Programm bricht. Die nächste Zeile ist falsch:

v_char.push_back(*(uchar*)(image.data+ i + j)); 

Sie müssen i nicht zu erhöhen, haben Sie zu erhöhen i + image.step. Es wird so sein:

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i*image.step + j));    

     }   
    } 
1

ich völlig verstehe nicht, warum Sie einen Vektor verwenden müssen, aber wenn es wirklich notwendig ist, empfehle ich Ihnen eine einfache Memcpy zu tun:

vector<byte> v_char(image.width * image.height); //Allocating the vector with the same size of the matrix 
memcpy(v_char.data(), image.data, v_char.size() * sizeof(byte)); 
5

Verbesserung auf Jav_Rocks Antwort hier ist, wie ich es machen würde.

Mat image = ...; 
vector<byte> v_char(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
    memcpy(&v_char[i * image.cols], image.data + i * image.step, image.cols); 

EDIT: Initialisierung von Konstruktor wird genügend Speicherplatz zuweisen zusätzliche Umschichtung zu vermeiden, aber es wird auch alle Elemente im Vektor-Set auf dem Standardwert (0). Der folgende Code vermeidet diese zusätzliche Initialisierung.

Mat image = ...; 
vector<byte> v_char; 
v_char.reserve(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
{ 
    int segment_start = image.data + i * image.step; 
    v_char.insert(v_char.end(), segment_start, segment_start + image.cols); 
} 
+1

Sicher, ich mag diesen Weg besser –

+0

Warum brauchen Sie die für die memcpy? Warum nicht einfach den ganzen Speicher kopieren? –

+3

Weil im Allgemeinen Mat :: Schritt unterscheidet sich von Mat :: Cols. Dadurch können Sie beispielsweise die Matrix zuschneiden, ohne die Bytes tatsächlich neu zu organisieren. Sie können eine Submatrix erstellen, die ein Fenster auf eine andere Matrix verweist, ohne Daten zu kopieren. Und wenn Sie eine Zelle in der Submatrix ändern, ändern Sie tatsächlich eine Zelle in der ursprünglichen Matrix, auf die nur die Submatrix verweist. – Dialecticus

4

Sie haben bisher gute Antworten erhalten, aber das ist nicht Ihr Hauptproblem. Was Sie wahrscheinlich wollen vor Senden eines Bildes an einen Server ist komprimieren es.

Werfen Sie einen Blick auf cv::imencode(), wie Sie es komprimieren, und cv::imdecode(), um es zurück in eine OpenCV-Matrix im Server umzuwandeln. Drücken Sie einfach die Imencode-Ausgabe an eine Steckdose und Sie sind fertig.

Verwandte Themen