Programmieraufgabe: Bildkorrektur

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Programmieraufgabe: Bildkorrektur

    Ich habe in der Schule von einem Klassenkollege die Aufgabe bekommen, dieses Bild optisch zu verbessern. Das hab ich zwar probiert, hat aber nicht gut funktioniert. Stattdessen hab ich ein bisschen was anderes gebastelt.
    Und zwar: Wenn man ein Bild wie dieses nimmt:
    (Die Bilder sind zu groß für die Dateianhangsfunktion)
    Und darauf mit roter Farbe ein bisschen herumkritzelt:

    Dann kommt am Ende das heraus:

    Wenn die Bilder genau vergleicht, kann man den Unterschied erkennen.

    Meine Herausforderung an euch: einen Algorithmus entwickeln, der das macht. Mich würde nämlich interessieren, wie man da noch herangehen kann. Wie ungültige Pixel erkannt werden und wie genau sie korrigiert werden sollen, überlasse ich euch.
    Auch die Sprache ist frei wählbar, aber ich würde euch bitten, möglichst .Net zu verwenden (soll ja im Sinne dieses Forums bleiben).


    Meine Methode:
    Zuerst wird ein Array von Boolean erstellt. Jedes Pixel wird auf Gültigkeit geprüft und das Ergebnis wird im Array an der entsprechenden Stelle abgelegt. Für die Prüfung hab ich ein Callback verwendet:

    VB.NET-Quellcode

    1. Private Shared Function CheckCorrectionColor(ByVal Pixel As Color) As Boolean
    2. Return Pixel.R = 255 AndAlso
    3. Pixel.G = 0 AndAlso _
    4. Pixel.B = 0
    5. End Function
    6. Function CorrectPixels(..., CheckCorrectionColorCallback As Func(Of Color, Boolean)) ...
    7. '...
    8. End Function
    9. 'Aufruf:
    10. ... CorrectPixels(..., AddressOf CheckCorrectionColor)
    Dadurch kann einfach angepasst werden, was als fehlerhaftes Pixel gilt (zumindest nach Farben). Im Moment werden alle Pixel, die genau rot sind, ersetzt.

    Dann wird jedes Pixel nochmal durchlaufen: Wenn es gültig ist, wird es einfach in die Ziel-Bitmap kopiert. Wenn es ungültig ist, passiert folgendes:
    Alle Pixel in einem angegebenen Abstand (funktioniert bei mir relativ gut mit 20 Pixeln) nach Entfernung zum geprüften Pixel gruppiert (auf 2 Dezimalstellen gerundet). Bei der ersten Gruppe, die gültige Pixel enthält, wird der Durchschnitt aller gültigen Pixel in der Gruppe berechnet und dem geprüten Pixel zugewiesen.
    Das Ganze hab ich noch mit Parallel.For abgerundet.

    Das Beispielbild benötigt bei mir ca. 9.5 Sekunden. Die Zeit steigt aber dramatisch, wenn die Anzahl an zu korrigierenden Pixeln steigt. Das Originalbild benötigt nur ca. 250ms.
    Da werde ich noch versuchen, ein bisschen was zu optimieren.


    (An die Moderation: Ich habe das im Off-Topic-Bereich gepostet, weil ich mir nicht sicher war, wie gut es in ein anderes Unterforum passt.)
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Niko Ortner schrieb:

    Meine Methode
    Nimm einen Median-Filter entsprechender Größe.
    Wende ihn unabhängig voneinander auf die R, die G und die B-Komponente an.
    Du kannst den Filter sehr oft über das Bild laufen lassen, die Qualität wird davon nicht schlechter.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!