Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Rimorzione Difetti jpg
Forum - C# / VB.NET - Rimorzione Difetti jpg

Avatar
Thejuster (Member)
Guru^2


Messaggi: 1717
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 14:47
Lunedì, 13/12/2010
Era da tempo che non chiedevo aiuto sul form

avete persente le immagini jpg che se proviamo a colorare il background,
rimangono delle traccie dell'immagine precedente andando ad incasinare la successiva..

hmm guardate.

http://img171.imageshack.us/img171/350/esempiot.png

l'immagine a sinistra e quella originale semplicemente modificata con il paint
e cliccando col colore nero su una parte dello sfondo.
come vedete lo sfondo viene rimosso parzialmente e rimane il bianco
sfarfallato

a destra l'immagine modificata tramite l'algoritmo per eliminare automaticamente l'imperfezione dello sfondo.


Codice sorgente - presumibilmente C++

  1. private void button2_Click(object sender, EventArgs e)
  2.         {
  3.             SaveFileDialog sv = new SaveFileDialog();
  4.             sv.Filter = "File png(*.png)|*.png|File Bitmap(*.bmp)|*.bmp|File jpg (*.jpg)|*.jpg";
  5.  
  6.             if (sv.ShowDialog() == DialogResult.OK)
  7.             {
  8.                 Bitmap bmp = new Bitmap(file);
  9.                 int width = bmp.Width;
  10.                 int height = bmp.Height;
  11.                 Dictionary<Point, int> currentLayer = new Dictionary<Point, int>();
  12.                 currentLayer[new Point(0, 0)] = 0;
  13.                 currentLayer[new Point(width - 1, height - 1)] = 0;
  14.                 while (currentLayer.Count != 0)
  15.                 {
  16.                     //mappatura dell'immagine
  17.                     foreach (Point p in currentLayer.Keys)
  18.                         bmp.SetPixel(p.X, p.Y, Color.Black);
  19.                     Dictionary<Point, int> newLayer = new Dictionary<Point, int>();
  20.                     foreach (Point p in currentLayer.Keys)
  21.                         foreach (Point p1 in Neighbors(p, width, height))
  22.                             if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40)
  23.                                 newLayer[p1] = 0;
  24.                     currentLayer = newLayer;
  25.                 }
  26.  
  27.                 bmp.Save(sv.FileName);
  28.             }
  29.         }
  30.  
  31.  
  32.         static int Distance(Color c1, Color c2)
  33.         {
  34.             int dr = Math.Abs(c1.R - c2.R);
  35.             int dg = Math.Abs(c1.G - c2.G);
  36.             int db = Math.Abs(c1.B - c2.B);
  37.             return Math.Max(Math.Max(dr, dg), db);
  38.         }
  39.  
  40.  
  41.         static List<Point> Neighbors(Point p, int maxX, int maxY)
  42.         {
  43.             List<Point> points = new List<Point>();
  44.             if (p.X + 1 < maxX) points.Add(new Point(p.X + 1, p.Y));
  45.             if (p.X - 1 >= 0) points.Add(new Point(p.X - 1, p.Y));
  46.             if (p.Y + 1 < maxY) points.Add(new Point(p.X, p.Y + 1));
  47.             if (p.Y - 1 >= 0) points.Add(new Point(p.X, p.Y - 1));
  48.             return points;
  49.         }



purtroppo come vedete dall'immagine alcuni difetti meglio dire residui dell'immagine
rimangono. conoscete un modo migliore per ovviare a questo difetto?

magari qualche consiglio su come implementare o migliorare l'algoritmo usato



Ultima modifica effettuata da Thejuster il 13/12/2010 alle 14:49


PM
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1717
Iscritto: 04/05/2008

Up
0
Down
V
Segnala al moderatore
Postato alle 16:45
Lunedì, 13/12/2010
uhm si piu o meno era questo il ragionamento che avevo fatto.
cioè dare una tolleranza minima di un colore che poi tende a verificarne la tonalità con una tolleranza come qui esempio.

if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40)

l'idea e stata utile, forse dovrei fare in modo che quando si riscontri una differenza molto notevole allora interrompo se ovviamente si tratti di un canale differente.

provo e ti faccio sapere grazie della dritta saluti :)


PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Up
0
Down
V
Segnala al moderatore
Postato alle 17:05
Lunedì, 13/12/2010
Ti converrebbe trasformare la coordinate RGB nello spazio HSL, che è molto più adatto a verificare la "somiglianza" di colori a causa del parametro hue.


"Infelici sono quelli che hanno tanto cervello da vedere la loro stupidità."
(Fligende Blatter)

"Dubitare di se stessi è il primo segno d'intelligenza."
(Ugo Ojetti)
PM
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2764
Iscritto: 21/09/2007

Up
-1
Down
V
Segnala al moderatore
Postato alle 15:22
Lunedì, 13/12/2010
potresti implementare un secchiello "magico" che, dato un pixel di partenza, riempie tutti i vicini che sono dello stesso colore più un delta calibrato sul caso in esame.

non dovrebbe essere difficile implementarlo in C# :)


Ingegnere Informatico
https://ldlagency.it
PM