Hallo Community,
ich möchte mir ein Programm schreiben, mit dem prüfen kann ob mein zweites Bild den gleichen Hintergrund hat, wie das erste Bild.
Wenn dann z.B. ein Pixel des Hintergrundes mit dem des ersten Bildes übereinstimmt, soll dieser Pixel transparent werden.
Ich habe schon ein bisschen versucht, bin allerdings nicht zu dem gewünschten Ergebnis gekommen.
Bei Bilder mit 150 x 150 Pixel funktioniert alles.
Wenn ich allerdings ein Bild mit einer Größe von 1080 x 1920 Pixel vergleichen möchte, reagiert das Programm nicht mehr.
Hier ist meine momentane Methode dazu:
/// <summary>
/// Vergleicht die zwei Bilder und ersetzt die gleichen Pixel
/// </summary>
/// <param name="firstpath">Pfad des ersten Bild</param>
/// <param name="secondpath">Pfad des zweiten Bild</param>
private void Compare(string firstpath, string secondpath)
{
// Erstes Bild
Bitmap src = new Bitmap(firstpath);
// Zweites Bild
Bitmap comp = new Bitmap(secondpath);
// Prüfen ob beide Bilder sie gleiche Größe haben
if (src.Width == comp.Width && src.Height == comp.Height)
{
for (int y = 0; y < src.Width; y++)
{
for (int x = 0; x < src.Height; x++)
{
try
{
if (src.GetPixel(x, y) == comp.GetPixel(x, y))
{
comp.SetPixel(x, y, Color.Transparent);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
pictureBox1.Image = src;
}
else
{
MessageBox.Show("Die Bilder haben nicht die gleiche Größe!");
}
}
Ich weis, das die "Bitmap.GetPixel()"-Methode sehr langsam ist, dennoch wollte ich es erst so probieren.
Ich hoffe, Ihr könnt mir bei meinem Problem weiterhelfen.
Mit freundlichen Grüßen
Slayerofyourmind
Hallo slayerofyourmind,
hilft dir:
Doppelte (bzw. ähnliche) Bilder finden
Unterschied zweier Bilder berechnen
Schnelle Verfahren zur Bildähnlichkeitsanalyse
Bilder vergleichen: Ähnlichkeit feststellen, auch wenn der Bildausschnitt etwas verschoben ist
weiter?
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hallo,
es hilft nicht unbedingt.
Ich möchte damit solche Bilder, wie das im Anhang, machen können.
GetPixel und SetPixel sind unheimlich langsam. Müsste eigentlich auch in der Doku stehen.
Nutze die Lock... Methode.
Die Pixel sind meistens nicht zu 100% identisch wenn die Aufnahmen hintereinander gemacht wurden.
Ein Pixel auf transparent setzen bringt nichts. Du müsstest die Pixel aus dem Vergleichsbild in das bestehende einfügen dort die Person zu sehen ist die im bestehenden noch nicht ist.
Dabei hast du das Problem dass nicht nur dann Unterschiede sind wenn die Person eingefügt werden soll, sondern auch an Stellen wo sie bisher war und jetzt nicht mehr ist. An dieser Stelle würdest du also die Person wieder löschen.
Als Lösungsansatz könntest du mehrere Bilder miteinander vergleichen. Wenn eine Stelle in zwei Bildern annähernd gleich ist und im dritten sehr unterschiedlich, wird das die Person sein. Diese Stelle setzt du dann in dein Zielbild ein.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo allerseits,
die Performance-Tips helfen aber nicht viel, wenn schon der eigentliche Algorithmus ungeeignet ist, weil er auf einer falschen Annahme basiert. Diese Aufgabenstellung läßt sich nicht mit einem einfachen Pixel-Vergleich lösen. Aber es gibt bereits Lösungen, die man nachbauen kann, Stichwort: Luminanz-Keying bzw. Color-Keying oder ganz allgemein: Compositing.
Christian
Weeks of programming can save you hours of planning
Hallo,
vielen Dank für die Antworten.
Ich habe mir noch mal alles überlegt, und möchte es nun anderst machen.
Ich habe eine Methode, mit der der Benutzer selbst den Bereich, in dem die Person oder das Objekt ist, festlegen kann.
Jeder Mausklick fügt den Punkt zu einer Liste hinzu. Am Ende, wird über ein "Refresh", das Paint-Event aufgerufen, um mit:
Pen pen = new Pen(Color.Black, 3);
Graphics g = e.Graphics;
g.DrawPolygon(pen, _points.ToArray()); //_points ist die Liste mit den Punkten
die Punkte in der Liste zu einem Polygon zu verbinden.
Ist es nun möglich, die Linie und alles außerhalb des Polygons transparent zu machen ?
Mit freundlichen Grüßen
Slayerofyourmind
Ist es nun möglich, die Linie und alles außerhalb des Polygons transparent zu machen ?
Ja, natürlich. Du hast alle Funktionen der Graphics-Klasse zur Verfügung: Graphics Overview (Windows Forms).
Abgesehen davon ist es allerdings wenig zielführend, hier irgendwelche Ideen zu posten, die einem gerade einfallen, und dann zu warten, bis dir jemand einen Lösungsweg vorgibt. Du solltest lieber erstmal im PhotoShop (oder in Paint.NET) ausprobieren, wie man solche Bilder zusammenfügt, welche Funktionen man dafür benötigt und wie man diese Funktionen anwendet. Dann kannst du deine Anforderungen definieren, und das ganze mit C# umsetzen.
Christian
Weeks of programming can save you hours of planning