Cast 1DArray in 2DArray



  • #Hab die Frage leider gerade zuerst im C Forum gestellt deshalb nochmals#
    hallo
    also ich habe folgendes Problem
    ich habe ein 1d Array (bilddaten). Nun ist meine Frage ob ich das Array auch als 2d Array nutzen kann, ohne die Daten zu kopieren. Da ich das Array meistens als 1d Array nutze kann ich es nicht im vorhinein als 2d Array anlegen.

    also im Programm sieht das ungefähr so aus

    #define imgWidth 5
    #define imgHeight 3
    
    //bild array anlegen
    int *img1dP=new int[imgWidth*imgHeight];
    
    //daten aus einem buffer kopieren
    memcpy(img1dP,buffer,imgWidth*imgHeight);
    
    //als beispiel zeile 3 spalte 3 in 4 ändern
    img1dP[2*imgWidth+2]=4;
    
    //jetzt würd ich gerne sowas änliches haben
    //aber so funktionierts natürlich noch nich
    int img2dP[imgHeight][imgWidth]=img1dP;
    

    Mir wurde empfohlen:

    int array1d[12];
    int (*array2d)[3][4] = array1d;
    

    Da mußte ich aber lernen, dass das nur im C Compiler geht nicht unter C++

    dankeschön



  • Zugriff auf Position x,y bei 32 Bit Pixel (zeilenorientiert):

    img1dP[x + y*ImageWidth];
    

    jetzt würd ich gerne sowas änliches haben

    In C++ schreibt man sich eine entsprechende Abstraktion in Form einer Klasse.

    struct image_adapter
    {
        int* data;
        int width; height;
    
        int& operator()(int x, y)
        {
            return data[x + y*width];
        }
    };
    
    // usage:
    image_adapter iadpt = {img1dP, ImageWidth, ImageHeight};
    
    // access pixel
    iadpt(32, 57)
    

  • Mod

    Unter C++ würdest du nichts davon jemals so machen. Soll es wirklich C++ sein oder traust du dich nicht zu fragen, wie du deinen Compiler in den C-Modus setzt? Dann definier dein Problem mal genauer. Es ist ja schon verdächtig, dass du die Daten hier in einem rohen Array hast, wo das doch offensichtlich nicht so gewünscht ist. Das macht man nicht so in einer Sprache, die es so einfach macht, komplexe Datentypen zu verwenden. Du scheinst C in C++ zu programmieren. Keine gute Idee.
    Man würde sich hier einen passenden Datentyp bauen, der die gewünschten Zugriffe anbietet. Was genau dabei passend ist, kommt auf deine Motivation an. Es soll ja wohl um Bilddaten gehen.



  • Hallo Ok!

    Ja also es sollte schon C++ sein. Ich kenn mich aber definitiv besser in C aus merkt man glaub ich (;-)). Die C++ Elemte brauchte ich bis jetzt nur um das Programm Modular in Klassen zu halten. Ich habe aber sonst noch nicht viele andere Elemente von C++ benutzt.

    Zum Problem:

    Ja genau es geht um Bilddaten. Die krieg ich vom v4l(video for Linux) Treiber. Das ist der memcpy Teil. Die kopiere ich mir dann in mein Array. In diesem Fall in den Speicher auf den *img1dP zeigt.

    Ja und auf die Daten will ich dann möglichst schnell zugreifen können.
    Aktione die ich in dem Speicher mache sind u.a.:
    Faltung Bayerdaten-> Grayscale
    Bildmerkmale extrahieren

    Also ziemlich viele zugriffe auf den Speicherbereich. Da wärs halt gut wenn ich den Speicher unterschiedlichen Adressieren könnte, da für die Faltung eine kontinuierliche Adressierung besser ist(1D Array) und für die Merkmals extraktion, wegen häufiger Sprünge, ein 2D Aufbau besser ist.

    Naja das ist das Problem in kurzform.

    Ja ich weiss wäre besser wegen mangelndem wissen in C++ das in c zu machen. Das ist aber auch vorgabe von meiner Firma das in c++ zu machen. Also muss ich mich da dran halten



  • Ach so um schonmal mit meinem geringen wissen in c++ zu glänzen

    Also ich hab zwei Möglichkeiten gefunden die ich aber beide nich so toll fand

    überladen des operators [] mit x+y*rowSize -> das macht aber ja dann genau das selbe was ich auch mache

    und das andere war mit Vektoren zu arbeiten. Aber nach dem wie ich das verstanden habe bringt mir das keinen geschwindigkeits vorteil. Eher nachteile.



  • flexbex schrieb:

    überladen des operators [] mit x+y*rowSize -> das macht aber ja dann genau das selbe was ich auch mache

    1.) ich ueberlade oben nicht operator[]. 2.) Du sparst dir, jedesmal rowSize. 3.) Im Endeffekt macht jeder moegliche Vorschlag das gleiche, nur ist operator() angenehmer zu benutzen (meistens).

    Vektoren zu arbeiten. ... Eher nachteile.

    1.) Mein Beispiel benutzt kein std::vector. 2.) Ich glaube kaum, dass du std::vector bewerten kannst. Geschwindigkeit sollte gleich sein.

    das keinen geschwindigkeits vorteil

    Wenn das deine Hauptsorge ist, dann wuerdest du sowieso Bibliotheken wie OpenCV oder Intels Performance Primitives (IPP) benutzen.



  • Im Titel steht was von Cast, also könnte man ganz naiv mal versuchen zu casten:

    int (*array2d)[3][4] = (int (*)[3][4]) &array1d;
    


  • Hallo wollte deinen Beitrag garnicht kritisieren sondern nur schreiben was ich bis jetzt gfeunden hatte. Wie gesagt bin wirklich kein C++ Profi.

    knivil schrieb:

    flexbex schrieb:

    überladen des operators [] mit x+y*rowSize -> das macht aber ja dann genau das selbe was ich auch mache

    1.) ich ueberlade oben nicht operator[]. 2.) Du sparst dir, jedesmal rowSize. 3.) Im Endeffekt macht jeder moegliche Vorschlag das gleiche, nur ist operator() angenehmer zu benutzen (meistens).

    Vektoren zu arbeiten. ... Eher nachteile.

    1.) Mein Beispiel benutzt kein std::vector. 2.) Ich glaube kaum, dass du std::vector bewerten kannst. Geschwindigkeit sollte gleich sein.

    Danke! Kannte bis jetzt nur OpenCv hatte mir das aber auch noch nicht weiter
    angeschaut. Ich hatte aber gehört das OpenCv nicht gerade Geschwindigkeits optimiert ist. Da ich aber zusätzlich auch noch auf einer begrenzten Linux Embedded Platform arbeite muss ich eh schauen welceh Bibliotheken ich nutzen kann.

    das keinen geschwindigkeits vorteil

    Wenn das deine Hauptsorge ist, dann wuerdest du sowieso Bibliotheken wie OpenCV oder Intels Performance Primitives (IPP) benutzen.

    IPP scheint aber nicht umsonst zu sein (ich schreib ne Masterarbeit deshalb kein budget)

    @Bashar dankeschön das funzt 🙂
    ABER jetzt habe ich ein 3d Array 😡
    das würd ich aber in kauf nehmen
    array2d[0][3][4]



  • flexbex schrieb:

    @Bashar dankeschön das funzt 🙂
    ABER jetzt habe ich ein 3d Array 😡
    das würd ich aber in kauf nehmen
    array2d[0][3][4]

    Nein, du hast einen Zeiger auf ein 2D-Array. (Ich denk du machst seit Jahren C?)

    Da wir in C++ sind, kannst du auch eine Referenz nehmen, dann entfällt das händische Dereferenzieren:

    int (&array2d)[3][4] = (int (&)[3][4]) array1d;
    


  • Danke.
    Aber Ihr muesst jetzt nicht staendig meine Kompetenz hinterfragen (bin kein Informnatiker und will hier bestimmt nicht den Eindruck vermitteln besonders gut in einer Programmiersprache zu sein).
    Hatte mich nur ueber die Schreibweise gewundert die mein Debugger mir angeboten hatte *array1d[0][0] fuer das erste Element bzw array1d[0][0][0]

    Aber bis jetzt habe ich 2Dimesionale Arrays noch nicht wirklich mit zeigern genutzt deshalb die Verwunderung.

    Thx


Log in to reply