Endlosschleife keine Rückgabe

  • Themenstarter Themenstarter Gelöschtes Mitglied 71416
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 71416

Gast
Hi,

ich versuche den höchsten Pixelwert im Array zu ermitteln, aber bekomme mit diesem Code keine Rückgabe und sämtliche Methoden, in denen ich max() aufrufe, funktionieren ebenfalls nicht.

Java:
  public int max() {
        Picture maximumfinden = new Picture(bild);
        Pixel[] pixelfeld = maximumfinden.getPixels();
        Pixel max;
        max = pixelfeld[0];
        for (int i = 0; i < pixelfeld.length; i++) {
            Pixel bildpunkt = pixelfeld[i];
            int grau = (bildpunkt.getRed() + bildpunkt.getGreen() + bildpunkt.getBlue()) / 3;
            bildpunkt.setRed(grau);
            bildpunkt.setGreen(grau);
            bildpunkt.setBlue(grau);
            if (bildpunkt.getRed() > max.getRed()) {
            max = pixelfeld[i];
            }
        }
        return max.getRed();
     }
 
dann kommentier alles aus bis du den grund gefunden hast

wenn du den grund hast warums abschmiert, löse es ... wenn du nicht mal weißt worans liegt wie sollst du dann eine Lösung finden ?
 
Wie groß ist das Array? Generell ist es schlecht, lang laufende Dinge in dem UI Thread zu machen. Das dürfte vermutlich der Fall sein, wenn Du sagst:
und die Grafische Oberfläche reagiert nicht mehr.

Hier hilft es dann auch oft, so Methoden in Unit Tests zu testen - da bekommt man dann auch die Laufzeit mit und kann ggf. Gegenmaßnahmen treffen.
 
Wie groß ist das Array? Generell ist es schlecht, lang laufende Dinge in dem UI Thread zu machen. Das dürfte vermutlich der Fall sein, wenn Du sagst:


Hier hilft es dann auch oft, so Methoden in Unit Tests zu testen - da bekommt man dann auch die Laufzeit mit und kann ggf. Gegenmaßnahmen treffen.
Das sollte eigentlich kein Problem sein, ich nutze das gleiche Array auch in anderen Methode ohne Rückgaben und da läuft alles flüssig. Wenn ich den Wert in der Methode probeweise ausgeben lasse, funktioniert das auch alles, also liegt es irgendwie an der Rückgabe.
Denke mittlerweile aber, dass das Problem eher bei Netbeans liegen muss und nicht beim Code selbst
 
Java:
int grau = (bildpunkt.getRed() + bildpunkt.getGreen() + bildpunkt.getBlue()) / 3;

Ist aber nicht die Umrechnung in Grauwerte so wie es das menschliche Auge sieht.

Grauwert = 0,299 × Rotanteil + 0,587 × Grünanteil + 0,114 × Blauanteil





Was genau ist denn das Problem?
Bleibt deine Methode hängen?
Wird der falsche wert zurückgeben?
 
Java:
int grau = (bildpunkt.getRed() + bildpunkt.getGreen() + bildpunkt.getBlue()) / 3;

Ist aber nicht die Umrechnung in Grauwerte so wie es das menschliche Auge sieht.

Grauwert = 0,299 × Rotanteil + 0,587 × Grünanteil + 0,114 × Blauanteil





Was genau ist denn das Problem?
Bleibt deine Methode hängen?
Wird der falsche wert zurückgeben?
Okay, aber ist bei dem Algorithmus nicht das Problem, dass ich zwischen int und double hin und her springe?


Das Problem ist, dass ich gar keinen Output bekomme. Die Methode funktioniert und ermittelt auch den richtigen Wert, aber gibt nichts zurück, sondern das Programm hängt sich dann einfach auf.
 
Also generell glaube ich nicht, dass es an Netbeans liegen kann. Eine Entwicklungsumgebung startet ja auch einfach nur einen Java Prozess. Das ist also nichts anderes, als wenn Du es ohne Entwicklungsumgebung startest. (Maximal wäre denkbar, dass Du es im Debug Modus startest und irgendwelche Breakpoints gesetzt hast. Aber dann würdest Du in NetBeans ja sehen, dass er irgendwo angehalten hat!)

Und diese Aussage macht so keinen Sinn:
Das Problem ist, dass ich gar keinen Output bekomme. Die Methode funktioniert und ermittelt auch den richtigen Wert, aber gibt nichts zurück, sondern das Programm hängt sich dann einfach auf.
Entweder die Methode funktioniert und gibt dann auch den Wert zurück oder sie funktioniert eben nicht. Und ein Programm hängt sich nicht einfach auf.

Da wir aber nicht den ganzen Code von Dir kennen, können wir diesbezüglich nichts sagen. Du kannst natürlich Ausgaben in deinen Code aufnehmen - dann siehst Du relativ schnell, ob der Code an gewisse Stellen kommt oder eben nicht.
Des Weiteren solltest Du genau prüfen: Hast Du evtl. try / catch Konstrukte wo Du im catch nichts ausgibst oder so?

Okay, aber ist bei dem Algorithmus nicht das Problem, dass ich zwischen int und double hin und her springe?
Wo springst Du hin und her? Was für ein Typ gibt denn getGreen zurück?
 
Er wird mit der Aussage vermutlich gemeint haben, dass er dann Gleitkommazahlen hat, wenn er Deine Berechnung nutzt. Die Werte selbst müssen int Werte sein, weil es sonst nicht übersetzbar wäre ohne Expliziten Cast.

Daher: Wenn Du mit der genauen Rechnung:
Grauwert = 0,299 × Rotanteil + 0,587 × Grünanteil + 0,114 × Blauanteil
arbeiten willst, dann wäre ein cast notwendig, also sowas wie:
int grau = (int) (0.299 * bildpunkt.getRed() + 0.587 * bildpunkt.getGreen() + 0.114 * bildpunkt.getBlue());

Aber das sind unabhängige Probleme! Nicht zu viel auf einmal vermischen! Mach einen Punkt nach dem anderen! Also sollte die Frage ausschließlich sein, wo dein Programm bisher nicht richtig funktioniert. Ob die Grauwerte nun stimmig sind oder nicht ist dabei erst einmal nebensächlich.
 
Naja, weil Code gezeigt gewurde, der logisch aber nicht richtig ist, also Fehler enthält?
also folgendermaßen

if (bildpunkt.getRed() > max.getRed()) {
max = pixelfeld;
}


dieses if statement auch wenn es theoretisch in JEDER if abfrage das max setzt bzw es niemals tut hat es keinerlei auswirkung darauf dass sich der thread aufhängt der GUI da in der for schleife ( die den thread aufhängt ) nirgendwo anders benutzt wird

es KANN nicht der grund sein außer er hat bei der .getRed methode einen fehler programmiert
FALLS dies der fall sein sollte müsste sich die schleife schon bei
int grau = (bildpunkt.getRed() + bildpunkt.getGreen() + bildpunkt.getBlue()) / 3;
dem aufhängen
somit kann das if nicht der grund sein, ob das if ansich sinnlos ist weis ich nicht, kann sein dass es von der logik unsinnig ist aber das ist ja nicht wichtig ,das fällt später auf 😉
 
Ich habe probeweise jetzt mal eine einfache Methode eingefügt, aber da das gleiche Problem: Das return wird nicht abgearbeitet.

Java:
public String returnTest() {
String ans = "Test";
return ans;
}

Ich werde mal probieren, das irgendwie anders zu lösen. Trotzdem danke!
 
Dann zeige doch mal wo und wie du die Methode aufrufst.
Naja ich hab jetzt erstmal probehalber einen Button dafür auf meiner Grafischen Oberfläche gemacht, um die Methode zu testen. Aufruf in der GUI Klasse:

Java:
private void jButton9ActionPerformed(java.awt.event.ActionEvent evt) {                                        
        bb.max();
    }

Da wo ich es dann wirklich brauche, sähe es dann so oder so ähnlich aus:

Java:
bildpunkt.setRed(255 * ((bildpunkt.getRed() - min()) / (max() - min())));
 
Wie gesagt wurde müsste man mal die Klassen wie Pixel und so sehen sowie deren Methoden um was sagen zu können.
Frage ist, was ist mit "hängt sich auf" gemeint?

Grundsätzlich ist immer denkbar dass da, warum auch immer, ein nicht zulässiger Wert versucht wird zurückzugeben, also bspw. null, falscher Typ oder auch ein leerer String oder so.
 
Ich bin jetzt erstmal zu meiner ursprünglichen Variante zurück, wo ich Minimum und Maximum direkt in der Methode ermittle... Da ist nur das Problem, dass ich bei dem Code die Fehlermeldung bekomme, dass durch 0 geteilt wird, weil am Anfang natürlich min und max gleich sind. Wenn ich aber vor die Formeln unten eine if Bedingung packe, dass das nur ausgeführt wird, wenn die Zahlen unterschiedlich sind, dann bekomme ich nur ein fast schwarzes Bild zurück und nicht das was ich will, nämlich nur einen verstärkten Kontrast. Hat jemand eine Idee, wo in dem Code der Fehler liegt?

Java:
    public void kontrast() {
        Picture neuesbild = new Picture(bild);
        Pixel[] pixelfeld = neuesbild.getPixels();
        Pixel max;
        Pixel min;
        max = pixelfeld[0];
        min = pixelfeld[0];
        for (int i = 0; i < pixelfeld.length; i++) {
            Pixel bildpunkt = pixelfeld[i];
            int grau = (int) (0.299 * bildpunkt.getRed() + 0.587 * bildpunkt.getGreen() + 0.114 * bildpunkt.getBlue());
            bildpunkt.setRed(grau);
            bildpunkt.setGreen(grau);
            bildpunkt.setBlue(grau);
            if (bildpunkt.getRed() > max.getRed()) {
            max = pixelfeld[i];
            }
            if (bildpunkt.getRed() < min.getRed()) {
            min = pixelfeld[i];
            }
            bildpunkt.setRed(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
            bildpunkt.setGreen(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
            bildpunkt.setBlue(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
            }
        neuesbild.show();
    }
 
Die Identische Berechnung in 3 aufeinander folgenden Zeile muss nicht sein, man könnte das Ergebnis auch zwischenspeichern:
Java:
            bildpunkt.setRed(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
            bildpunkt.setGreen(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
            bildpunkt.setBlue(255 * ((bildpunkt.getRed() - min.getRed()) / (max.getRed() - min.getRed())));
Die Frage ist: Was wird denn erwartet, wenn max.getRed() - min.getRed() == 0 ergibt?
Java:
            int red = calculateRed(bildpunkt, min, max);
            bildpunkt.setRed(red);
            bildpunkt.setGreen(red);
            bildpunkt.setBlue(red);
...
    private static int calculateRed(final Pixel bildpunkt, final Pixel min, final Pixel max) {
        final int t = max.getRed() - min.getRed();
        if (t != 0) {
            return 255 * ((bildpunkt.getRed() - min.getRed()) / t);
        }
        return Integer.MAX_VALUE; // oder was auch immer dann erwartet wird
    }
 
Du willst doch hier sowas wie eine Tonwertkorrektur machen Tonwert-Spreizung.

Dazu brauchst du ja den hellsten und dunkelsten Pixel im Bild. Eigentlich müsstes du das Array zweimal durch gehen einmal um die beiden Tonwerte zu finden und dann um die neuen Werte zu setzen. Ist der hellste Wert zb nur 230 kannst du alle Hellen Pixel spreizen.
Denn max ist 255, und min ist 0, als Luminanz Helligkeit

Bei den Tiefen das gleiche. Die Spreizung ist auch nicht unbedingt linear.

Eine sogenannte Gradationskurve.


Das was du hier versuchst wird sicherlich nicht den Effekt haben den du erwartest.
Auch wenn dein Code keinen Fehler mehr werfen wird.
 
Zuletzt bearbeitet:
Du hast zb 230 als hellste Pixel, 255 ist das maximum also kannst du eine Korrektur um
255-230 = 25 Tonwerte machen.

Bei den Tiefen das gleiche umgekehrt

Ist der hellste Pixel 255 und der tiefste 0 gibt es keine automatische Spreizung.
Dann kommen die Gradationskurven zum Kontrast steigen zum Einsatz.
 
Zuletzt bearbeitet:
Also meint ihr mit einer zweiten Schleife in der gleichen Methode, wo ich dann nur die Veränderung der Grauwerte mit der Formel abarbeite? Das Problem ist ja eigentlich gerade, dass die Formeln erst zum Zuge kommen dürften, wenn die Schleife einmal durchs Feld ist. Wäre das denn überhaupt möglich, das in einer Methode zu machen? 😀
 
Alles in einer Methode würde ich nicht machen.

Erstmal würde ich eine Methode machen die den hellsten und tiefsten Luminanz Wert zurückgibt.
Aus einen Bitmap, entweder du macht für die Rückgabe eine Klasse oder benutzt ein Array.

Dann würde ich eine Methode zum Spreizen machen die als Übergabe das Bitmap und den Anfang der Spreizung für die Tiefen und der Lichter sowie Mitten bekommt.
In der Methode wirst du dann auch die min-max Methode aufrufen müssen.

Packe nicht alles in eine Methode. Teilbereiche sollte man ausgliedern.


 
Zuletzt bearbeitet:
Ich verstehe nicht ganz was das Endziel ist.

Aktuell änderst du für jedes Pixel des Bildes dessen rgb werte so ab dass rot=grün=blau=mittelwert der irsprünglichen rgb werte ist.

Ansonsten guckst du nebenher welches dieser Pixel nach der Transformation den größten rot wert hat (da du ja eh rot, grün, blau gleich setzt, ist es egal ob du hier rot, grün oder blau fürs maximumsuchen betrachtest)

Sehe grundsätzlich keinen Fehler, auch wenn mir der SInn hinter der Aktion noch nicht klar ist.

Methodenintern sehe ich direkt kein Problem, daher würde ich eher vermuten dass der übergebene input n sich bereits "fehlerhaft" ist.
Will sagen, dass die bild variable vielleicht null ist,
je nachdem wie die Klasse aussieht, ist vielleicht bild ein Attribut auf das die methode gar nicht zugreifen kann.
Oder es wird aus irgendeinem grund vll. bild=null was auch zu allerlei Fehlern führen kann.

Jedenfalls, wenn bild das ist, was es sein sollte, müsste die Methode eigentlich funktionieren.

Wie rufst du denn die Methode auf, gibt es vielleicht da Fehler?


Oder, was einr echt primitiver Fehler wäre, rufst du max(bild) auf (also ohne System.out.println(...) durm herum)
und erwartest trotzdem eine konsolenausgabe?
 
hier eine einfache Lösung nur für die Lichter.

Java:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class DisplayImage {
    public static void main(String[] args) throws IOException {
        new DisplayImage();
    }

    public DisplayImage() throws IOException {
        File file = new File("pizzdunk.jpg");
        BufferedImage bufferedImage = ImageIO.read(file);

        setAutoLichter(bufferedImage);

        ImageIcon imageIcon = new ImageIcon(bufferedImage);
        JFrame jFrame = new JFrame();

        jFrame.setLayout(new FlowLayout());

        jFrame.setSize(500, 500);
        JLabel jLabel = new JLabel();

        jLabel.setIcon(imageIcon);
        jFrame.add(jLabel);
        jFrame.setVisible(true);

        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }


    void setAutoLichter(BufferedImage bi){
        LumMinMax minMax = getMinMaxLum(bi);
        int max = minMax.getMax();
        int diff = 255-max;

        for (int x = 0; x < bi.getWidth(); x++) {
            for (int y = 0; y < bi.getHeight(); y++) {
                int rgb = bi.getRGB(x,y);

                int r = (rgb & 0xff0000) >> 16 ;
                int g = (rgb & 0xff00) >> 8;
                int b = rgb & 0xff;
                r+=diff;
                g+=diff;
                b+=diff;

                rgb = r;
                rgb = rgb<<8;
                rgb+=g;
                rgb = rgb<<8;
                rgb+=b;

                bi.setRGB(x,y,rgb);

            }
        }
    }

    LumMinMax getMinMaxLum(BufferedImage bufferedImage) {
        int min = 0;
        int max = 0;
        int lum;

        for (int x = 0; x < bufferedImage.getWidth(); x++) {
            for (int y = 0; y < bufferedImage.getHeight(); y++) {
                int rgb = bufferedImage.getRGB(x, y);
                lum = getLom2Pixel(rgb);
                if (lum > max) {
                    max = lum;
                }
                if (lum < min) {
                    min = lum;
                }
            }
        }
        return new LumMinMax(min, max);
    }

    int getLom2Pixel(int rgb) {
        int r = (rgb & 0xff0000) >> 16;
        int g = (rgb & 0xff00) >> 8;
        int b = rgb & 0xff;
        return (int) (0.299 * r + 0.587 * g + 0.114 * b);
    }

}

Java:
public class LumMinMax {
    private int min;
    private int max;

    public LumMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public int getMin() {
        return min;
    }

    public int getMax() {
        return max;
    }

}
 
Ich hab's jetzt erstmal so gelöst, dass ich ich Minimum und Maximum in anderen Methoden berechne und hier dann nur noch das hier:
Ich teste die Bearbeitung des Bildes nochmal mit Photoshop, aber erstmal funktioniert das jetzt so 🙂

Java:
 public void kontrast() {
        Picture neuesbild = new Picture(bild);
        Pixel[] pixelfeld = neuesbild.getPixels();
        int max = max();
        int min = min();
        for (int i = 0; i < pixelfeld.length; i++) {
            Pixel bildpunkt = pixelfeld[i];
            double t = max - min;
            double s = ((bildpunkt.getRed() - min) / t);
            int done = (int) (255 * s);
            bildpunkt.setRed(done);
            bildpunkt.setGreen(done);
            bildpunkt.setBlue(done);
        }
        neuesbild.show();
    }
 
Java:
LumMinMax getMinMaxLum(BufferedImage bufferedImage) {
        int min = 255;
       ...
sorry das ist sinvoller sonnt kommt ja immer 0 raus.
 
Ich hab's jetzt erstmal so gelöst, dass ich ich Minimum und Maximum in anderen Methoden berechne und hier dann nur noch das hier:
Ich teste die Bearbeitung des Bildes nochmal mit Photoshop, aber erstmal funktioniert das jetzt so 🙂

Java:
 public void kontrast() {
        Picture neuesbild = new Picture(bild);
        Pixel[] pixelfeld = neuesbild.getPixels();
        int max = max();
        int min = min();
        for (int i = 0; i < pixelfeld.length; i++) {
            Pixel bildpunkt = pixelfeld[i];
            double t = max - min;
            double s = ((bildpunkt.getRed() - min) / t);
            int done = (int) (255 * s);
            bildpunkt.setRed(done);
            bildpunkt.setGreen(done);
            bildpunkt.setBlue(done);
        }
        neuesbild.show();
    }
Hier kommt doch maximal ein SW Bild raus, und keine Farbe.
 

Neue Themen


Zurück
Oben