Zeiger als 3d Array

FJK

Erfahrenes Mitglied
Hallo,

ich habe eine opencv Mat. (RGB Bild). Die Daten liegen im speicher wie ein 3D Array.
Ich bekomme zwar ein Zeiger auf die Daten, jedoch keinen 3D Zeiger.

also Das Funktioniert:
Code:
Mat A = imread(...);
byte *p = A.data();
Ich hätte aber gerne:
Code:
Mat A = imread(...);
byte ***p = A.data();

kann mir bitte jemand helfen?

Eigentlich würde ja schon reichen, irgendwie sowas zu machen:

Code:
byte* p;
byte ***z;

z = p;

hab es schon über Unions versucht, jedoch ohne erfolg.
danke
 
Zuletzt bearbeitet von einem Moderator:

sheel

I love Asm
Hi

hat Mat überhaupt ein data() ? Kanns grad nicht finden...

Für eine funktionierende Lösung reichts nicht zu wissen, dass es ein "3D-Array" sein soll.
Es fehlen die drei Größen, ob es ein zusammenhängender Block oder Pointerarrays sind, ob der Datentyp dahinter überhaupt "byte" ist und was das eigentlich ist, ob am Ende einer "Zeile" Padding ist, usw.
 

Technipion

Erfahrenes Mitglied
Äh lol,
@FJK kannst du bitte die Frage wieder reinmachen. Ich kann ja verstehen, dass man ab und zu einen Beitrag von sich wieder löscht, aber ein Thread ohne Thema macht irgendwie keinen Sinn... o_O
Vielleicht haben irgendwann andere Leute ein ähnliches Problem wie du und könnten von dieser Lösung profitieren. Ich vermute mal es ging um mehrdimensionale Arrays à la
C++:
/// statisch:
int Matrix[4][5] = { {1, 0, 0, 0, 2},
                     {0, 1, 0, 0, 4},
                     {0, 0, 1, 0, 6}
                     {0, 0, 0, 1, 8} };


/// dynamisch:
int **MatrixSizeUnknown;

MatrixSizeUnknown = new int* [Height];

for (uint i = 0; i < Height; i++)
    MatrixSizeUnknown[i] = new int [Width];

// now is it MatrixSizeUnknown[Height][Width]

for (uint i = 0; i < Height; i++)
    delete [] MatrixSizeUnknown[i];

delete [] MatrixSizeUnknown;

// now it's dead

Falls der Thread gelöscht wird, isses für mich okay.
Gruß Technipion
 

Jennesta

Erfahrenes Mitglied
Hallo,

ich habe eine opencv Mat. (RGB Bild). Die Daten liegen im speicher wie ein 3D Array.
Ich bekomme zwar ein Zeiger auf die Daten, jedoch keinen 3D Zeiger.

Die grundsätzliche Frage, die sich mir stellt ist. Was hast du denn eigentlich vor?
Die Daten liegen normalerweise bei OpenCv eben nicht als 3D Array vor sondern als 1d continuous array.

Unter folgendem Link sind diverse möglichkeiten an die einzelnen Pixel dran zu kommen.
Alternativ gibt es noch die Methode "at"

C++:
template<typename T> T& Mat::at(int i, int j, int k)

Diese empfehle ich aber aufgrund von Geschwindigkeit nicht bei großen Datenmengen, sondern die Variante "fast access" aus dem Link.
 

Technipion

Erfahrenes Mitglied
Ich habe hier mal einen quick'n'dirty Codeschnipsel der zeigt, wie man eindimensionale Arrays mehrdimensional betrachten kann.

C++:
#include <iostream>


int main(int argc, char* argv[])
{
    typedef unsigned char byte;
   
    byte Array1D[] = { 1,  2,  3,     4,  5,  6,
                       7,  8,  9,    10, 11, 12,
                      13, 14, 15,    16, 17, 18,
                      19, 20, 21,    22, 23, 24 };
    // Sagen wir die Daten sind 2 x 4 x 3
    // Also quasi ein 2 x 4 Bild mit je ein Byte für R,G,B
   
    byte (*Array3D)[2][3] = (byte (*)[2][3])Array1D;
   
    for (int y = 0; y < 4; y++)
        for (int x = 0; x < 2; x++)
            std::cout << x << ", " << y << ": RGB = "
                      << (int)Array3D[y][x][0] << ", "
                      << (int)Array3D[y][x][1] << ", "
                      << (int)Array3D[y][x][2] << std::endl;
   
    return 0;
}

Falls die Hantierung mit rohen Zeigern gewünscht ist. Ansonsten bietet, wie Jennesta schon geschrieben hat, OpenCV allerhand Möglichkeiten an die Daten ranzukommen.

ob der Datentyp dahinter überhaupt "byte" ist
Das soll sich ja in C++17 mit std::byte ändern :D

Gruß Technipion
 

sheel

I love Asm
Das soll sich ja in C++17 mit std::byte ändern
Warum? Es geht ja darum, ob diese Funktion ein Array davon liefert, nicht ob es den Typ irgendwie gibt (und ob std:: gemeint ist, oder cv::, oder irgendein typedef...). (Ja, sicher kann man ein Array von anderen plain Typen auch zu std::byte casten, und für den Typ ist es wegen Aliasingzeug nicht mal verboten, aber trotzdem...)

Btw., imho ist std::byte so ein Thema, dass sie ruhig rauslassen könnten :/
Es ist nur im Sprachgebrauch vom Standard ein "Byte" (ein enum aus unsigned char, und unsigned char kann auch größer als 8bit sein), und Konsistenz wäre auch schön (byte oder std::byte_t, auch doch keine Mischung...)
 
Zuletzt bearbeitet: