|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Pixel detection
Ciao a tutti!
Vi pongo una questione interessante: Avendo un immagine in bianco e nero, con dei bordi bianchi, si vogliono tagliare i bordi bianchi e far sì che l'immagine rimanga senza i bordi bianchi. L'immagine in questione è di forma quadrata e l'angolo superiore ed inferiore sinistro dell'immagine iniziano sempre con pixels neri. Questo ci consentirebbe di dedurre la grandezza di un angolo per tagliare il superfluo bordo bianco, ma il problema rimane sempre l'individuazione dell'angolo in alto a sinistra e di quello in basso a sinistra: se riuscissi ad individuare il primo pixels in alto a sinistra e l'ultimo in basso a sinistra, otterrei la distanza tra questi (l'angolo di un quadrato) e riuscirei poi a tagliare tutti i bordi circostanti sapendo da quali coordinate di origine partire per il taglio facendo un cropping. :-? Voi che ne pensate? come posso riuscire ad individuare il primo pixel nero di un immagine? Spero ci sia qualcuno in gamba in grado di darmi una risposta! |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Posta l'immagine che fai prima.
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Con che formato immagine lavori? Che linguaggio?
|
![]() |
![]() |
![]() |
#4 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Lavoro con jpg,o anche png che dovrebbe essere meglio per i pixels.
In pratica sto sviluppando un decoder in java per trattare simboli come quello allegato, e funziona per immagini standard cioè che ho prodotto io e di cui conosco le dimensioni del bordo, ma vorrei saper tagliare anche immagini che abbiano dimensione diversa da quella che riesco a creare io con il mio programma di creazione. Il fatto è che non conosco come localizare (parlando in termini di pixel), le estremità dell'immagine così da poter tagliare i bordi bianchi. Notate che l'immagine ha sempre alcune estremità nere, e sono quelle che vedete in figura. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Te devi eliminare il bordo azzurro?
![]() |
![]() |
![]() |
![]() |
#6 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Esatto!
|
![]() |
![]() |
![]() |
#7 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Devo eliminare il bordo azzurro, però supponendo di non sapere che ha grandezza 30 pixel come in questo caso, ma la grandezza del bordo può essere variabile.
A me è venuta in mente l'idea di localizzare gli angoli neri, ma non sò come, o meglio, forse con pixelgrubber, ma non riesco a far funzionare pixelgrubber. |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Dovresti creare una bufferedimage e disegnarci sopra l'immagine, a quel punto con getRGB(int x,int y) ricavi il colore del pixel di coordinate (x,y)
Ultima modifica di MEMon : 13-03-2008 alle 13:44. |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Puoi usare la classe BufferedImage: contiene molti metodi utili per lavorare ed editare immagini.
Poi se devi modificare il file finale o solo la sua rappresentazione a video lo sai tu. Nel primo caso (modifica file) dovresti: - creare una BufferedImage del tuo file da modificare; - eidtare la BufferedImage; - salvare la BufferedImage in un file (sovvrascrivendo quello di partenza); Nel secondo caso: - creare una BufferedImage del tuo file da visualizzare senza il bordo; - editare la BufferedImage; - mandare a video il contenuto della BufferedImage; Qui javadoc per BufferdImage Qui un articolo interessante di Chet Haase (consigliato!) Infine, puoi scrivere in u file la tua BufferedImage grazie al metodo statico write() della classe javax.imageio.ImageIO. Questo è l'esempio che ho trovato: Codice:
public static boolean write(RenderedImage im, String formatName, File output) throws IOException Here im is the RenderedImage to be written, formatName is the String containg the informal name of the format (e.g. png) and output is the file object to be written to. An example usage of the method for PNG file format is shown below: ImageIO.write(image, "png", file); You can also use getReaderFormatNames method of the same class to learn available informal format names understood by the current set of registered readers. Ciao ![]() Ultima modifica di banryu79 : 13-03-2008 alle 14:00. |
![]() |
![]() |
![]() |
#10 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Grazie,
Ok, ci sono, per il momento ho bufferizzato l'immagine: Codice:
public class PixelDetection extends Canvas{ BufferedImage bimage; String imageName; Image imgSelected; public static int width = 400; public static int height = 400; public PixelDetection(){ acquisisciImmagine(); } public void acquisisciImmagine(){ // Acquisisco il nome dell'immagine da shell DataInputStream inputImageName = new DataInputStream(System.in); System.out.println("Scrivi il nome dell'immagine da bufferizare comprensiva di estensione: "); try{ imageName = inputImageName.readLine(); }catch(Exception e){} // Definisco l'immagine scelta: imgSelected = Toolkit.getDefaultToolkit().getImage(imageName); bufferizzaImmagineSelezionata(imgSelected); } public void bufferizzaImmagineSelezionata(Image image){ // Creo una buffered image di tipo RGB bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // Creo un oggeto grafico che contiene il contenuto del buffer Graphics g = bimage.createGraphics(); // Copia l'immagine selezionata nel buffer g.drawImage(image, 0, 0, null); g.dispose(); } public void scanPixels(BufferedImage bimage){ } Ora mi rimane da scansionare i pixel, trovare l'inizio dell'immaigne, talgiarla e salvarla. La bufferizzazione è corretta? |
![]() |
![]() |
![]() |
#11 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Mi correggo, forse è meglio se bafferizzassi in questo modo...
Codice:
// Acquisisco il nome dell'immagine da shell DataInputStream inputImageName = new DataInputStream(System.in); System.out.println("Scrivi il nome dell'immagine da bufferizzare comprensiva di estensione: "); try{ imageName = inputImageName.readLine(); }catch(Exception e){} try{ String fileName = imageName; File file = new File(fileName); bimage = ImageIO.read(file); }catch(Exception ex){} Codice:
public int getPixel(int x, int y) { return bimage.getRGB(x, y); } Codice:
System.out.println("PIXEL: "+getPixel(31,31)); Cosa significa? Devo codificarlo in qualche cosa?? |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Codice:
int argb = bufferedImage.getRGB(x, y); // ottiene il valore RGB del pixel int alpha = (argb >> 24) & 0xff; // ottiene il componente Alpha int red = (argb >> 16) & 0xff; // ottiene il componente Red int green = (argb >> 8) & 0xff; // ottiene il componente Green int blue = argb & 0xff; // ottiene il componente Blue ![]() |
|
![]() |
![]() |
![]() |
#13 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Ora mi è più chiaro, grazie!
![]() |
![]() |
![]() |
![]() |
#14 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Allora, intanto ti ringrazio, ma premetto che non conoscendo il valore del nero mi è difficile individuare il bianco.
Non so neanche come creare il nero, non riesco a trovare nulla riguardo la composizione dei colori nel modo che mi hai segnalato. Comunque sò che il valore del bianco è -1, del nero -16514044 in numerico. Potrei trovarlo anche così ma non è efficace se l'immagine non è perfettamente in bianco e nero. ![]() Se sapessi la composizione del nero lo valuterei con il pixel in scansione.. Mi hai detto come fare il red, il green, il blue, potresti dirmi come fare il nero? Purtroppo non basta fare nero = 0,0,0 non è così? |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Il bianco corrisponde ai valori massimi per tutte e tre le componenti (R,G,B).
Il nero è l'esatto opposto, corrisponde ai valori minimi (0 tutte e 3) Se noti nell'esempio dell'ultimo post che ho pubblicato, alla fine ottieni dei valori di tipo intero per ogni singola componente. La scala di questi valori va da 0 a 255. Quindi bianco = R255 G255 B255; nero = R0 G0 B0. Se devi individuare il colore bianco, ma il tuo "bordo" non è perfettamente bianco allora dovrai stabilire te una "soglia"; Per esempio (ma vado a spanne, devi verificare a video il colore) puoi decidere di utilizzare una soglia che parte da valore 250 in su (max 255). Se tutte e tre le componenti sono > del valore deciso, allora sei nella soglia. @EDIT: Giustamente tu stai cercando gli "estremi" dell'immagine caratterizzati da pixel neri. (nero = R0 G0 B0) Puoi stabilire una soglia tipo da 0 a 5 (vado sempre a spanne). Con questa soglia ti cerchi gli estremi (primo pixel significativo in alto a sinistra, ultimo pixel significativo in basso a destra). A quel punto, la tua immagine "pulita" è il subset di pixel compresi tra il primo e l'ultimo. Ciao ![]() Ultima modifica di banryu79 : 14-03-2008 alle 18:44. |
![]() |
![]() |
![]() |
#16 |
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Bene!
Grazie al tuo aiuto sono riuscito a trovare le coordinate del primo pixel nero dell'immagine. Codice:
public void scanPixel(BufferedImage imgToScan){ w = imgToScan.getWidth(); h = imgToScan.getHeight(); int originX; int originY; int actualPixel; boolean founded = false; for(int row = 0; row < h; row++){ // Per ogni riga dell'immagine if (founded == false){ for(int col = 0; col < w; col++){ // Controlla ciascun pixel che costituisce la riga actualPixel = imgToScan.getRGB(col,row); // Ottengo le componenti RGB del pixel scansionato: //int alpha = (actualPixel >> 24) & 0xff; // ottiene il componente Alpha int red = (actualPixel >> 16) & 0xff; // ottiene il componente Red int green = (actualPixel >> 8) & 0xff; // ottiene il componente Green int blue = actualPixel & 0xff; // ottiene il componente Blue // // Verifica Soglia colori // boolean r = false; boolean g = false; boolean b = false; int soglia = 1; if((red == 0)||(red < soglia)){ r = true; System.out.println("RED: " +red); } if((green == 0)||(green < soglia)){ g = true; System.out.println("GREEN: " +green); } if((blue == 0)||(blue < soglia)){ b = true; System.out.println("BLUE: " +blue);} if(r == g == b == true){ System.out.println("FOUND PIXEL AT "+col +" " +row); originX = col; // Setto le coordinate di origine originY = row; founded = true; System.out.println("Ora posso tagliare l'immagine partendo dal punto x: "+originX +" y: " +originY); break; } } //For interno } else{ break; } } // For Esterno } |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Mi pare che il primo pixel (quello in alto a sinistra) così lo trovi.
Trovi anche l'ultimo eseguendo la scansione iniziando dall'ultimo e iterando all'indietro. Con questi due pixel (coppia di XY) dovresti essere in grado di completare il tuo task e ottenere l'immagine che desideravi. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:54.