2017-03-04 3 views
1

Quick Zusammenfassung:Mat-Zellen in OpenCV auf NULL gesetzt?

ich eine cv :: Mat von

cv::Mat m = cv::Mat::zeros(MAP_HEIGHT, MAP_WIDTH, CV_8UC1) 

Mein Ansatz danach, wenn ich alle Polygone in einer Liste von Polygonen, um zu sehen, und wenn ich tue, füllen sie in und schließlich weise ich m zu meiner öffentlichen cv :: Mat Karte zu (definiert in der Header-Datei). Was passiert, ist im Grunde:

cv::Mat m = cv::Mat::zeros(MAP_HEIGHT, MAP_WIDTH, CV_8UC1); 
// possibly fill polygons with 1's. Nothing happens if there are no polygons 
map = m; 

Die Logik meines Programms ist, dass Position x, y erlaubt, wenn eine 0 in die Zelle einnimmt. Also keine Polygone => alle Karten sollten "echt" sein.

Ich habe diese Methode definiert, um zu überprüfen, ob eine gegebene x-y-Koordinate erlaubt ist.

bool Map::isAllowed(bool res, int x, int y) { 
    unsigned char allowed = 0; 
    res = (map.ptr<unsigned char>(y)[x] == allowed); 
} 

Jetzt beginnt das Geheimnis.

cout << cv::countNonZero(map) << endl; // prints 0, meaning all cells are 0 
for(int i = 0; i < MAP_HEIGHT; i++) { 
    unsigned char* c = map.ptr<unsigned char>(i); 
    for(int j = 0; j < MAP_WIDTH; j++) { 
     cout << c[j] << endl; 
    } 
} // will print nothing, only outputs empty lines, followed by a newline. 

Wenn i (c [j] == NULL) drucken druckt 1. Wenn ich die gesamte Mat i nur 0 sehen, drucken zu blinken über die LCD-Display, so dass sie dort deutlich.

Warum gibt isAllowed (bool, x, y) für (0,0) false zurück, wenn dort eindeutig eine 0 ist?

Lassen Sie mich wissen, wenn weitere Informationen benötigt werden, danke!

+1

Verwenden Sie 'cout << int (c [j]) << endl;'. Sie drucken das ASCII-Zeichen, nicht den Wert. ('NULL' ist einfach' 0'). Und 'map.ptr (y) [x]' kann einfach umgeschrieben werden als 'map.at (y, x)', oder wenn Sie 'Mat1b' als' map (y, x) 'verwenden – Miki

+0

@Miki Das druckt tatsächlich 0, danke. Zusatzfrage; Warum bekomme ich das gleiche Ergebnis, das ich vorher hatte, wenn ich (unsigned char) c [j] mache, aber ich bekomme tatsächliche 0, wenn ich int (c [j]) mache? Ich hatte einen Fehler, wo ich int von der Mat gesammelt und gelesen habe, aber ich wollte unsigned Chars. Wenn die Matte mit 1 gefüllt wurde, würde dies den numerischen Wert des Inhalts der 4 folgenden Zellen ergeben. –

+0

Wenn Sie 'uchar' Daten drucken, erhalten Sie den ASCII Wert. Um den tatsächlichen Wert zu erhalten, können Sie in "int" umwandeln. Da 'uchar' 1 Byte und 'int' 4 Bytes ist, schreiben Sie einen 'int' Wert in einem' uchar * 'Sie schreiben effektiv auf 4' uchar's – Miki

Antwort

0

Problem ist nun gelöst, hier sind meine Fehler für die Zukunft:

1: Beim Drucken @ Miki wies darauf hin, dass vorzeichenlose Zeichen -> ASCII-Wert gedruckt wird, keine numerische Darstellung.

2: in isAllowedPosition (bool res, int x, int y), res hat einen primitiven Typ. Auch dies wird auf den Stack geschoben und kein Verweis auf eine Speicherstelle. Wenn ich dazu schreibe, schreibe ich in die lokale Kopie und nicht in die als Argumet übergebene.

Zwei mögliche Fixes, übergeben Sie entweder einen Zeiger auf einen Speicherort und schreiben Sie, oder einfach das Ergebnis zurück.

+0

Oder einfach "res res;" – Miki

0

Da Ihr Datentyp uchar ist (aka unsigned char), drucken Sie den ASCII-Wert. Verwenden Sie

cout << int(c[j]) << endl; 

, um den tatsächlichen Wert zu drucken.


Auch map.ptr<unsigned char>(y)[x] kann einfach als map.at<uchar>(y,x) neu geschrieben werden, oder wenn Sie Mat1b verwenden als map(y,x)

+0

isAllowed (res, 0, 0) gib immer noch falsch zurück. Ich habe die Methode entsprechend geändert, indem ich vor dem Vergleich ins int gewandelt habe. unsigned Zeichen * c = map.ptr (y); int cellval = int (p [x]); res = Zelle == int (0); –

+0

Sie müssen nur nach int umwandeln, um den Wert auszudrucken, nicht in Ihrer Verarbeitung. – Miki

+0

Ich habe es gelöst, vielen Dank für Ihre Hilfe @Miki. :) –

Verwandte Themen