Differenza tra immagini

di Anonimizzato6441 il
18 risposte
Salve,
ho provato a fare una differenza tra immagini in java, caricate da disco, ma l'immagine risultante è nera, potete dare uno sguardo al mio codice?
public void metodoDifferenza() throws IOException {
        BufferedImage image1 = ImageIO.read(new File("Foto/coloured-pencils.jpg"));
        BufferedImage image2 = ImageIO.read(new File("Foto/vai.jpg"));
        BufferedImage image3 = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());

       
        int img1H = image1.getHeight();
        int img1W = image1.getWidth();

        int img2H = image2.getHeight();
        int img2W = image2.getWidth();
        
        int argb1, alpha1, red1, green1, blue1;
        int argb2, alpha2, red2, green2, blue2;

        int aDiff, rDiff, gDiff, bDiff;
        int diff;

        if (img1H == img2H && img1W == img2W) {
            for (int x = 0; x < image1.getHeight(); x++) {
                for (int y = 0; y < image1.getWidth(); y++) {
                    argb1 = image1.getRGB(x, y);
                    argb2 = image2.getRGB(x, y);

                    alpha1 = (argb1 >> 24) & 0xFF;
                    red1 = (argb1 >> 16) & 0xFF;
                    green1 = (argb1 >> 8) & 0xFF;
                    blue1 = (argb1) & 0xFF;

                    alpha2 = (argb2 >> 24) & 0xFF;
                    red2 = (argb2 >> 16) & 0xFF;
                    green2 = (argb2 >> 8) & 0xFF;
                    blue2 = (argb2) & 0xFF;

                    aDiff = Math.abs(alpha1 - alpha2);
                    rDiff = Math.abs(red1 - red2);
                    gDiff = Math.abs(green1 - green2);
                    bDiff = Math.abs(blue1 - blue2);

                    diff = (aDiff << 24) | (rDiff << 16) | (gDiff << 8) | bDiff;
                    image3.setRGB(x, y, diff);
                }

            }
            this.setOriginalImage(image3);
        } else {
            
        }
    }
Grazie

18 Risposte

  • Ti consiglio di stampare a video alcune informazioni come la dimensione di ciascuna immagine di input (magari sono diverse e la differenza quindi non viene eseguita); inoltre ti consiglio di predisporre due immagini di input molto piccole (es. 4x4 pixel) e di stampare nel ciclo il valore delle componenti di ciascun pixel di ciascuna immagine. Buon lavoro!
  • Alla fine ho fatto una prova ho caricato la stessa foto, quindi ha stessa dimensione solo che mi genera la seguente eccezione
    java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    quando viene richiamato il metodo
    argb1 = image1.getRGB(x, y);
    , come posso risolvere?
    Grazie ancora
  • Crea due immagini piccole, credimi che risparmierai un sacco di tempo!
    Stampa a video le dimensioni delle due immagini e i valori di x e y ad ogni passata così trovi subito il problema. Buon lavoro!
  • Grazie per la disponibilità,
    le immagini che ho caricato adesso sono piccole, come dicevi prima, riesco a visualizzare la dimensione delle immagini correttamente ma non riesco a visualizzare i successivi valori perchè l'eccezione fa riferimento a getRGB che dovrebbe restituirmi il valore sul quale agire in seguito.
  • MariaMaria ha scritto:


                for (int x = 0; x < image1.getHeight(); x++) {
                    for (int y = 0; y < image1.getWidth(); y++) {
    
    Controlla le due condizioni!
  • Bene ho fatto delle stampe dei valori di x ed y, accade questo, la x = 0 e la y viene incrementata fino ad un certo punto,ad esempio x=0 eccezione
    Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    y=0, poi si arriva fino ad 8, perchè ho un'immagine 9X8, ed alla fine non viene incrementata la x, come mai? Dove sbaglio?
    Grazie
  • MariaMaria ha scritto:


    come mai? Dove sbaglio?
    Non vorrei sembrare scortese o pedante ma ...... ti spiace ri-controllare queste 2 (due!) righe?
                    for (int x = 0; x < image1.getHeight(); x++) {
                        for (int y = 0; y < image1.getWidth(); y++) {
    Se te le ho segnalate .... un motivo c'è.
  • Grazie andbin,
    ho fatto le seguenti prove:
    - ho commentato il corpo dei for ed ho sostituito il tutto con le sole stampe dei valori di x ed y
    - ho modificato il for in questo modo
     for (int x = 0; x <= image1.getHeight(); x++) {
                    for (int y = 0; y <= image1.getWidth(); y++) {
    ho quindi aggiunto = per poter avere tutti i valori, perchè così come scritto in precedenza le dimensioni dell'immagine non venivano rispettate, quindi i valori stampati di x ed y sono corretti
    - ho inserito un'unica riga nel for, la seguente:
    System.out.print("\nIL valore  di arg1 è :" + image1.getRGB(x, y));
    ed il risultato finale è che all'iterazione x = 0 ed y =8 lancia la seguente eccezione:
    Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    Adesso non riesco a capire cosa succede, se hai individuato il problema potresti darmi una dritta? anche perchè se fossero sbagliati i for perchè fermarsi all'ultima iterazione del for interno?
    Grazie
  • Ciao Maria,
    devi solo invertire la condizione di termine del for
    
    for (int x = 0; x <  image1.getWidth(); x++) {
         for (int y = 0; y < image1.getHeight(); y++) {
    
    per questo ti va in eccezione perché per come l'avevi strutturato te il valore di Y andava a 9 ma avendo un immagine di 8 pixel andava in ArrayIndexOutOfBoundsException.


  • MariaMaria ha scritto:


    Adesso non riesco a capire cosa succede, se hai individuato il problema potresti darmi una dritta?
    Scusa ma .... è così difficile guardare attentamente e "ragionare" su 2 (e dico due) righe di codice??
  • Grazie schumy2000 anche invertendo i for ottengo la stessa eccezione.

    Grazie andbin non riesco a ragionare sulle due righe, e se ho postato il tutto è perchè non ho trovato soluzione, ti ringrazio comunque per la disponibilità.
  • MariaMaria ha scritto:


    anche invertendo i for ottengo la stessa eccezione.
    Il problema è che forse ..... non vuoi ragionare (o ritieni che non ti serva .... il che è anche peggio) ..... non basta invertire i due for in sé. Nel tuo codice non è importante (e non cambia nulla) se scansioni righe/colonne o colonne/righe.

    Ti chiederei una cortesia: guarda i for che avevi scritto tu inizialmente:

    for (int x = 0; x < image1.getHeight(); x++) {

    Qui stai iterando sulla coordinata "x" ma stai prendendo la "altezza", ovvero la quantità di pixel sulla coordinata "y".

    for (int y = 0; y < image1.getWidth(); y++) {

    E questo è idem come sopra ma al contrario.
  • Scusatemi se ritorno su questo messaggio di qualche settimana fa, ho risolto l'errore grazie al vostro suggerimento, vorrei ora capire perchè il metodo mi restituisce un'immagine vuota anche se i valori ai ARGB non sono nulli, potrebbe esserci un problema in questa parte di codice?
    aDiff = Math.abs(a1 - a2);
                    rDiff = Math.abs(r1 - r2);
                    gDiff = Math.abs(g1 - g2);
                    bDiff = Math.abs(b1 - b2);
    perchè sostituendo l'operazione di sottrazione con la somma la nuova immagine la vede correttamente.
    Grazie
  • MariaMaria ha scritto:


    vorrei ora capire perchè il metodo mi restituisce un'immagine vuota
    aDiff = Math.abs(a1 - a2);
    Il punto "critico" è sicuramente il canale "alpha". 0x00=totalmente trasparente, 0xFF (255)=totalmente opaco.
    Se le due immagini hanno lo stesso valore di alpha, la sottrazione dà 0, quindi totalmente trasparente!
Devi accedere o registrarti per scrivere nel forum
18 risposte