Implementare filtro mediano

di il
16 risposte

Implementare filtro mediano

Salve,
dovrei implementare il filtro mediano per un'applicazione che gestisce immagini.
Ho trovato questo codice di esempio ma non funziona...
public void median_RGB(Immagine img) {

        int maskSize = 3;
        int width = img.getCaratteristiche().getLarghezzaFoto();
        int height = img.getCaratteristiche().getAltezzaFoto();
        int outputPixels[] = new int[width * height];
        
        int red[], green[], blue[];
        int xMin, xMax, yMin, yMax;

        int argb, reD, greenN, bluE;
        
        /** Median Filter operation */
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int a = img.getAlpha(x, y);
                red = new int[maskSize * maskSize];
                green = new int[maskSize * maskSize];
                blue = new int[maskSize * maskSize];
                int count = 0;
                xMin = x - (maskSize / 2);
                xMax = x + (maskSize / 2);
                yMin = y - (maskSize / 2);
                yMax = y + (maskSize / 2);
                for (int r = yMin; r <= yMax; r++) {
                    for (int c = xMin; c <= xMax; c++) {
                        if (r < 0 || r >= height || c < 0 || c >= width) {
                            /** Some portion of the mask is outside the image. */
                            continue;
                        } else {
                            argb = img.getOriginalImage().getRGB(c, r);
                            reD = (argb >> 16) & 0xff;
                            red[count] = reD;
                            greenN = (argb >> 8) & 0xff;
                            green[count] = greenN;
                            bluE = (argb) & 0xFF;
                            blue[count] = bluE;
                            count++;
                        }
                    }
                }

                /** sort red, green, blue array */
                java.util.Arrays.sort(red);
                java.util.Arrays.sort(green);
                java.util.Arrays.sort(blue);

                /** save median value in outputPixels array */
                int index = (count % 2 == 0) ? count / 2 - 1 : count / 2;
                logger.info("valore mediano " + index);
                int p = (a << 24) | (red[index] << 16) | (green[index] << 8) | blue[index];
                outputPixels[x + y * width] = p;
            }
        }
        /** Write the output pixels to the image pixels */
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                img.getOriginalImage().setRGB(x, y, outputPixels[x + y * width]);
            }
        }
    }
Eppure il valore delle varie componenti è diversa da zero, praticamente dopo averlo applicato non vedo più l'immagine
Potete darmi una dritta?
Grazie

16 Risposte

  • Re: Implementare filtro mediano

    Perché fai questo sort?

    java.util.Arrays.sort(red);
    java.util.Arrays.sort(green);
    java.util.Arrays.sort(blue);

    A quanto mi ricordo (reminiscenze universitarie) il filtro mediano era la media degli 8 pixel vicini,
    ma non veniva fatto alcun sort.
  • Re: Implementare filtro mediano

    Grazie Shumy2000,
    il filtro mediano sostituisce ogni pixel con il valore mediano nel suo intorno 3x3; i 9 pixel della finestra devono essere ordinati ed il pixel centrale deve essere sostituito con il valore mediano, per cui il sort mi serve per individuare il valore centrale.
    Ma la restante parte del codice presenta errori secondo te?
    Grazie
  • Re: Implementare filtro mediano

    Puoi chiarire cosa vuol dire "non vedo più l'immagine", in maniera più approondita?
  • Re: Implementare filtro mediano

    Carico l'immagine, aggiungo il rumore ed applico il filtro mediano per ridurre il rumore, solo che l'immagine scompare, non la visualizzo più, probabilmente i pixel vengono sostituiti tutti con il colore bianco... oppure non so cosa accade
  • Re: Implementare filtro mediano

    Un consiglio, procedi per step:
    1 - prova a caricare l'immagine e visualizzarla
    2 - prova a caricare l'immagine, inserire il rumore e visualizzarla
    se fin qui non hai avuto problemi, concentrati sulla tua funzione di filtraggio (perchè allora li c'è qualche problema)
    se a questo punto invece hai avuto problemi, il filtraggio non centra (almeno per ora)!
    Per il filtraggio, parti da qualcosa di semplice, esempio di riduci di 50 tutte le componenti di tutti i pixel, e vedi se ottieni l'effetto di rendere più scura l'immagine.
  • Re: Implementare filtro mediano

    Grazie per la risposta candaluar,
    1) l'applicazione carica correttamente l'immagine;
    2) inserisco il rumore e riesco ancora a visualizzarla
    appena applico il filtro mediano l'immagine scompare, per cui presumo che il problema sia contenuto all'interno del filtro mediano ma non capisco dove.
    Per il filtraggio, parti da qualcosa di semplice, esempio di riduci di 50 tutte le componenti di tutti i pixel, e vedi se ottieni l'effetto di rendere più scura l'immagine.
    Ho fatto questo
    alpha = (pixel >> 24) & 0xFF;
                    red = (pixel >> 16) & 0xFF;
                    green = (pixel >> 8) & 0xFF;
                    blue = pixel & 0xFF;
    
                    red = (red - 50);
                    green = (green - 50);
                    blue = (blue - 50);

    ed ottengo un'immagine non più scura ma con colori cambiati.
    Per cui penso che il problema si presente all'interno del filtro mediano ma non so bene come individuarlo.
    Grazie a tutti
  • Re: Implementare filtro mediano

    Dimentica, per ora, il filtro mediano.
    Non riesci a schiarire/scurire l'immagine per cui evidentemente c'è un errore su come leggi i componenti di ciascun pixel oppure su come riscrivi le componenti di ciascun pixel.
    Prova a postare il codice che esegue il chiaro/scuro così cerchiamo di capire cosa non va; ripulisci eventualmente codice inutile.
  • Re: Implementare filtro mediano

    Comunque questo non è completamente giusto
    red = (red - 50);
    green = (green - 50);
    blue = (blue - 50);
    dovresti fare (per tutte e tre le componenti):
    if( red > 50 )
       red = red - 50;
    else
       red = 0;
  • Re: Implementare filtro mediano

    Si volevo solo provare velocemente cosa accadeva...
    Ti sembra ora che il problema sia proprio contenuto nel metodo del filtro mediano?
  • Re: Implementare filtro mediano

    Ti sembra ora che il problema sia proprio contenuto nel metodo del filtro mediano?
    L'unica cosa che si può dire è che nel momento che modifichi l'immagine la corrompi; provare a chiarire/schiarire l'immagine serve per vedere se i pixel li carichi correttamente e poi li salvi correttamente. Se questo funzionasse potremmo poi concentrarci sul filtro vero e proprio perchè saremmo sicuri che i pixel li carichiamo correttamente e li salviamo al posto giusto.
  • Re: Implementare filtro mediano

    Grazie candaluar,
    forse sono stata un pò troppo superficiale prima, in effetti usando i controlli suggeriti da te nell'ultimo post, la mia immagine diventa più scura.
    Come faccio ora a capire cosa non va nel filtro mediano?
    Grazie ancora
  • Re: Implementare filtro mediano

    Ora si tratta di debuggare il cuore del tuo filtro perchè sappiamo che il caricamento dei pixel è corretto e anche il loro salvataggio.
    Crea, con un programma di disegn,o un'immagine piccola, es. 4x4 pixel a colori, e metti in ciascun pixel un valore diverso. Nel tuo programma dovresti avere 16 pixel da trattare, di cui 12 sul bordo (che quindi non subiscono trasformazioni) e 4 interni che vengono trattati.
    Inserisci un stampa a video del tipo "trattamento pixel" per quei pixel che devono essere trattati e dovresti avere 4 righe in output.
    Se questo è corretto, per quei 4 pixel aggiungi in stampa il risultato del sort e vedi dove sbaglia.
  • Re: Implementare filtro mediano

    Grazie candaluar,
    ho seguito i tuoi suggerimenti, per cui ho creato con paint un'immagine 4x4 ed ho provato ad inserire un pò di colori in modo sparso, ho fatto stampare i valori del pixel ed alla fine ho verificato che il sort venisse calcolato, ho quindi potuto vedere che i tre array contenti i valori di RGB vengono ordinati solo che ho notato una cosa, in pratica il filtro mediano dovrebbe sostituire il valore presente al centro della maschera, dopo aver ordinato l'array, con il valore mediano dell'array, ma se provo a farmi stampare il valore mediano quando il pixel preso in considerazione è in posizione (0,0) mi viene restituito il valore in posizione
    red[index] 
    dove
    index = 1
    in quanto
    count = 4
    sapendo che index viene calcolato
     int index = (count % 2 == 0) ? count / 2 - 1 : count / 2;
    l'array contente i valori di rosso, facendo sempre riferimento al pixel (0,0) è il seguente:
    
     red vettore 0
     red vettore 0
     red vettore 0
     red vettore 0
     red vettore 0
     red vettore 255
     red vettore 255
     red vettore 255
     red vettore 255
    per cui quando viene calcolato
    int p = (a << 24) | (red[index] << 16) | (green[index] << 8) | blue[index];
    che viene poi assegnato a
    outputPixels[x + y * width] = p;
    for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    img.getOriginalImage().setRGB(x, y, outputPixels[x + y * width]);
                }
            }
    
    In pratica non so se il tutto è corretto, potete darci un'occhiata
    Grazie
  • Re: Implementare filtro mediano

    Il mio suggerimento è di non fare niente sui pixel di contorno (ovvero con x=0 OPPURE x=width-1 OPPURE y=0 OPPURE y=height-1) quindi lavora solo sui pixel interni; inoltre, il valore mediano sarà sempre dato dalla combinazione di red[4], green[4] e blue[4]...
Devi accedere o registrarti per scrivere nel forum
16 risposte