Arithmetische Operationen mit Pointern



  • Ich möchte gerne den Code auf der folgenden Seite ganz unten(http://werner.yellowcouch.org/Papers/subimg/index.html) von C++ nach Java übertragen.

    Ich habe sehr wenig Erfahrungen mit Pointern und und habe Verständnisprobleme bei der Boxaveragefunktion

    typedef signed short signed2;
    
    signed2* boxaverage(signed2*input, int sx, int sy, int wx, int wy)
    {
      signed2 *horizontalmean = (signed2*)malloc(sizeof(signed2)*sx*sy);
      assert(horizontalmean);
      int wx2=wx/2;
      int wy2=wy/2;
      signed2* from = input + (sy-1) * sx;
      signed2* to = horizontalmean + (sy-1) * sx;
    

    Soweit ich es verstehe wird Speicher in der größe sxsy* singed shorts reserbiert und die Adresse horizontalmean zugewiesen.

    Assert bestätigt, dass dies geklappt hat und kein Nullverweis vorliegt.

    Was passiert nun bei der Variableninitialisierung von to? horizontalmean wird im Laufe des Programmes nicht mit einem Wert belegt, geht es hier nur um den Speicheroffset zwischen from und to? Wenn ja gibt es einen einfach Weg die Logik in Java zu übersetzen?

    Danke.



  • UnsingedSinged schrieb:

    Was passiert nun bei der Variableninitialisierung von to? horizontalmean wird im Laufe des Programmes nicht mit einem Wert belegt, geht es hier nur um den Speicheroffset zwischen from und to? Wenn ja gibt es einen einfach Weg die Logik in Java zu übersetzen?

    Ja, die Terme die bei der Zuweisung von from und to hinzu addiert werden sind soweit ich das sehe ein Speicheroffset relativ zu input und horizontalmean .

    In Java könnte man sowas zum Beispiel als Array-Offset übersetzen:

    int offset = (sy-1) * sx;
    

    Beim späteren Zugriff auf diese um das Offset verschobenen Pointer via Array-Index müsste man dann diese Indizes zuzätzlich addieren:

    Ein

    sum+=(signed8)from[xr];
    to[x]=sum/count;
    

    könnte man dann z.B. so schreiben:

    sum += (long) from[offset + xr];
    to[offset + x] = sum / count;
    

    Generell könnte es allerdings vorteilhafter sein zu verstehen, was da genau passiert und das Ganze dann Java-spezifisch neu zu implementieren anstatt nur den Code zu übersetzen (man versteht das Verfahren besser und überträgt keine C-Idiome (C++ ist in dem Code nur schwer auszumachen) nach Java, was meist keine gute Wahl ist).

    Gruss,
    Finnegan



  • UnsingedSinged schrieb:

    Was passiert nun bei der Variableninitialisierung von to?

    Das gleiche wie vorher bei from. :p

    to wird mit einem Zeiger auf das (sy-1)*sx-te Element von horizontalmean initialisiert.

    Wenn ja gibt es einen einfach Weg die Logik in Java zu übersetzen?

    Sicherlich, allerdings über Indizes statt Pointer.



  • Finnegan schrieb:

    Generell könnte es allerdings vorteilhafter sein zu verstehen, was da genau passiert und das Ganze dann Java-spezifisch neu zu implementieren anstatt nur den Code zu übersetzen (man versteht das Verfahren besser und überträgt keine C-Idiome (C++ ist in dem Code nur schwer auszumachen) nach Java, was meist keine gute Wahl ist).

    Gruss,
    Finnegan

    Ja, dass war auch meine Vermutung und wird meine herangehensweise sein. Ich werde wohl doch etwas mehr Zeit in dieses Projekt stecken müssen als angedacht war. Vielen dank euch allen.



  • UnsingedSinged schrieb:

    Ja, dass war auch meine Vermutung und wird meine herangehensweise sein. Ich werde wohl doch etwas mehr Zeit in dieses Projekt stecken müssen als angedacht war. Vielen dank euch allen.

    BTW: Wenn ich das richtig verstanden habe, scheint das ein Box-Filter zu sein, der dort implementiert ist. Das Verfahren ist eigentlich relativ simpel:
    Man durchläuft alle Pixel des Bildes und für jeden Pixel bestimmt man das Mittel der Bildpixel die sich in einer definierten Box mit dem aktuellen Pixel als mittelpunkt befinden. Dieser Mittelwert ist die Intensität des entsprechenden Pixels im gefilterten Bild. Dabei muss man allerdings auch den Rand berücksichtigen: So ist z.B. bei Pixel (0,0) ein Großteil der Box außerhalb des Bildes. Ich denke das gewünschte Ergebnis erzielt man, indem man annimt dass sich die "Randpixel" außerhalb des Bildes unendlich weit fortsetzen (clamping). Wenn man also die Intensität eines Pixels abfragt, und die Pixelposition außerhalb des Bildes liegt (kleiner 0 oder größer gleich Bildbreite/höhe), dann setzt man die Koordinate, die abzufragen ist einfach auf 0 (bzw. die Bildbreite/höhe minus 1).

    Bei Farbbildern wendet man so einen Boxfilter dann separat auf jedem Farbkanal an.

    Gruss,
    Finnegan


Anmelden zum Antworten