Rote-Augen-Reduktionsalgorithmus
-
02-07-2019 - |
Frage
Ich brauche für eine Anwendung Rote-Augen-Reduktion implementieren Ich arbeite an.
Googeln meist Links zu kommerziellen Endbenutzerprodukte.
Sie wissen einen guten roten Augen-Algorithmus, der in einer GPL-Anwendung verwendet werden könnte?
Lösung
Ich bin viel zu spät zur Party hier, aber für zukünftige Forscher habe ich den folgenden Algorithmus für eine persönliche App verwende ich geschrieben habe.
Vor allem die Region zu verringern, wird durch den Benutzer ausgewählt und übergeben Methode als Mittelpunkt und Radius zur Rote-Augen-Reduzierung. Das Verfahren durchläuft jedes Pixel innerhalb des Radius und führt die folgende Berechnung aus:
//Value of red divided by average of blue and green:
Pixel pixel = image.getPixel(x,y);
float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
if (redIntensity > 1.5f) // 1.5 because it gives the best results
{
// reduce red to the average of blue and green
bm.SetPixel(i, j, Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
}
Ich mag die Ergebnisse wirklich, weil sie halten die Farbintensität, die die Lichtreflexion des Auges bedeutet nicht verringert wird. (Das bedeutet, die Augen halten ihre „lebendig“ -Look.)
Andere Tipps
Zuerst müssen Sie die Augen sehen! Der normale Weg wäre, einen Kantendetektor läuft und dann ein Hough-Transformation zwei Kreise der gleichen Größe zu finden, aber es könnte einfacher Algorithmen sein, einfach Cluster von roten Pixeln zu finden.
Dann müssen Sie entscheiden, was sie mit zu ersetzen, vorausgesetzt, es gibt genug Grün / Blau-Daten im Bild, das Sie einfach den roten Kanal ignorieren können.
OpenCV ist eine sehr gute freie Bibliothek für die Bildverarbeitung, könnte es sein, viel des Guten für das, was Sie wollen - aber viele Beispiele und eine sehr aktive Community hat. Sie könnten auch für die Objektverfolgung Algorithmen suchen, ein farbiges Objekt in einer Szene-Tracking ist eine sehr similair und weit verbreitetes Problem.
Wenn sonst niemand mit direkterer Antwort kommt, könnte man immer herunterladen den Quellcode für GIMP und sehen, wie sie es tun.
Der einfachste Algorithmus, und noch eine, die sehr effektiv ist, wäre die R des RGB-Tripel Null aus der Region von Interesse.
Die rote verschwindet, aber die anderen Farben werden beibehalten.
Eine weitere Erweiterung dieses Algorithmus könnte beinhaltet den R-Wert der Tripel nur zur Nullung, wo rot die dominierende Farbe (R> G und R> B) ist.
Sie können imagemagick versuchen - ein paar Tipps auf dieser Seite, wie das
tunhttp://www.cit.gu. edu.au/~anthony/info/graphics/imagemagick.hints
Suche nach red Auge auf der Seite
Das Open-Source-Projekt Paint.NET hat eine Implementierung in C #.
Hier ist die Java-Implementierung Lösung
public void corrigirRedEye(int posStartX, int maxX, int posStartY, int maxY, BufferedImage image) {
for(int x = posStartX; x < maxX; x++) {
for(int y = posStartY; y < maxY; y++) {
int c = image.getRGB(x,y);
int red = (c & 0x00ff0000) >> 16;
int green = (c & 0x0000ff00) >> 8;
int blue = c & 0x000000ff;
float redIntensity = ((float)red / ((green + blue) / 2));
if (redIntensity > 2.2) {
Color newColor = new Color(90, green, blue);
image.setRGB(x, y, newColor.getRGB());
}
}
}
}
die aus zwei Rechtecken durch eine Anwendung wie offene cv erkannt abgerufenen Parameter zu sein (dies sollte ein Rechteck Einbeziehung die Augenposition sein)
int posStartY = (int) leftEye.getY();
int maxX = (int) (leftEye.getX() + leftEye.getWidth());
int maxY = (int) (leftEye.getY() + leftEye.getHeight());
this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);
// right eye
posStartX = (int) rightEye.getX();
posStartY = (int) rightEye.getY();
maxX = (int) (rightEye.getX() + rightEye.getWidth());
maxY = (int) (rightEye.getY() + rightEye.getHeight());
this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);
Dies ist eine vollständige Implementierung der Antwort von Benry bereitgestellt:
using SD = System.Drawing;
public static SD.Image ReduceRedEye(SD.Image img, SD.Rectangle eyesRect)
{
if ( (eyesRect.Height > 0)
&& (eyesRect.Width > 0)) {
SD.Bitmap bmpImage = new SD.Bitmap(img);
for (int x=eyesRect.X;x<(eyesRect.X+eyesRect.Width);x++) {
for (int y=eyesRect.Y;y<(eyesRect.Y+eyesRect.Height);y++) {
//Value of red divided by average of blue and green:
SD.Color pixel = bmpImage.GetPixel(x,y);
float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
if (redIntensity > 2.2f)
{
// reduce red to the average of blue and green
bmpImage.SetPixel(x, y, SD.Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
pixel = bmpImage.GetPixel(x,y); // for debug
}
}
}
return (SD.Image)(bmpImage);
}
return null;
}
Lesen Sie dieses Blog gibt es eine schöne Erklärung in Bezug auf Erkennung und Korrektur von roten Augen. Rote-Augen-Korrektur mit OpenCV und Python