Algorithmus zum Herunterskalieren von Bildern

7

Könnten Sie mir helfen, den richtigen Algorithmus für die Bildgrößenanpassung zu finden? Ich habe ein Bild von einer Nummer. Die maximale Größe ist 200x200, ich brauche ein Bild mit der Größe 15x15 oder noch weniger. Das Bild ist monochrom (schwarz und weiß) und das Ergebnis sollte das gleiche sein. Das ist die Info über meine Aufgabe.

Ich habe bereits einen Algorithmus ausprobiert, hier ist es

%Vor%

Aber es wird nicht mit der Abnahme eines Bildes funktionieren, was mein vorheriges Ziel ist. Könnten Sie mir helfen, einen Algorithmus zu finden, der dieses Problem lösen könnte (die Qualität muss nicht perfekt sein, die Geschwindigkeit spielt keine Rolle). Einige Informationen darüber wären perfekt, wenn man bedenkt, dass ich ein Neuling bin. Natürlich ist auch ein kurzes Stück c / c ++ - Code (oder eine Bibliothek) perfekt.

Bearbeiten: Ich habe einen Algorithmus gefunden. Wird es für die Komprimierung von 200 auf 20 geeignet sein?

    
user1131662 05.03.2012, 17:12
quelle

7 Antworten

10

Der allgemeine Ansatz besteht darin, die Eingabe zu filtern, um eine kleinere Größe zu generieren, und den Schwellenwert, der in monochrom konvertiert werden soll. Der einfachste zu implementierende Filter ist ein einfacher Durchschnitt, und er liefert oft OK-Ergebnisse. Der Sinc-Filter ist theoretisch der beste, aber es ist unpraktisch zu implementieren und hat klingelnde Artefakte, die oft unerwünscht sind. Viele andere Filter sind verfügbar, wie Lanczos oder Tent (das ist die verallgemeinerte Form von Bilinear).

Hier ist eine Version eines durchschnittlichen Filters in Kombination mit einer Schwellenwertfunktion. Angenommen, picture4 ist die Eingabe mit Pixelwerten von 0 oder 1, und die Ausgabe ist picture3 im selben Format. Ich nahm auch an, dass x die am wenigsten signifikante Dimension ist, die entgegengesetzt zu der üblichen mathematischen Notation und entgegengesetzt zu den Koordinaten in Ihrer Frage ist.

%Vor%

Ich habe diesen Code jetzt getestet. Hier ist das 200x200-Bild für die Eingabe, gefolgt von einer Reduzierung des nächsten Nachbarn auf 15x15 (erstellt in Paint Shop Pro), gefolgt von den Ergebnissen dieses Codes. Ich überlasse es Ihnen, zu entscheiden, welches dem Original treuer ist; der Unterschied wäre viel offensichtlicher, wenn das Original einige feine Details hätte.

    
Mark Ransom 05.03.2012 18:04
quelle
3

Da Sie mit einer Bibliothek arbeiten können, können Sie sich die imagemagick C ++ - Bindungen ansehen.

Sie können das Bild auch in einem einfachen Format wie pbm ausgeben und dann den Befehl imagemagick aufrufen, um die Größe zu ändern:

%Vor%

Beispielausgabedatei (Hinweis: Sie müssen für jede Zeile keine neue Zeile verwenden):

%Vor%

Die Ausgabedatei:

%Vor%     
strcat 05.03.2012 17:53
quelle
3

Ich habe eine Implementierung einer bilinearen Interpolation gefunden. C-Code.

Angenommen, dass:

a - ein primäres Array (das wir dehnen / komprimieren müssen) Zeiger.

oldw - primäre Breite

oldh - primäre Höhe

b - ein sekundäres Array (das wir nach dem Komprimieren / Strecken erhalten) Zeiger

neww - sekundäre Breite

newh - Sekundenhöhe

%Vor%

Ich hoffe, es wird für andere Benutzer nützlich sein. Aber ich zweifle immer noch, ob es in meiner Situation funktioniert (wenn man nicht stratcht, sondern ein Array komprimiert). Irgendwelche Ideen?

    
user1131662 06.03.2012 15:35
quelle
2

Ich denke, Sie brauchen Interpolation . Es gibt viele Algorithmen, zum Beispiel können Sie bilineare Interpolation

verwenden     
hired777 05.03.2012 17:16
quelle
2

Um ein Bild richtig zu verkleinern, sollten Sie Ihr Bild in quadratische Pixelblöcke aufteilen und dann etwas wie Bilineare Interpolation Um die richtige Farbe des Pixels zu finden, das den NxN-Pixelblock ersetzen soll, auf den Sie die Interpolation anwenden.

Da ich nicht so gut in Mathematik bin, werde ich nicht versuchen, dir ein Beispiel dafür zu geben, wie der Code aussehen könnte. Entschuldigung: (

    
Tony The Lion 05.03.2012 17:18
quelle
2

Wenn Sie Win32 verwenden, hilft möglicherweise die StretchBlt-Funktion.

Die Funktion StretchBlt kopiert eine Bitmap aus einem Quellrechteck in ein Zielrechteck und dehnt oder komprimiert die Bitmap, um sie bei Bedarf an die Abmessungen des Zielrechtecks ​​anzupassen. Das System streckt oder komprimiert die Bitmap gemäß dem aktuell im Zielgerätekontext festgelegten Streckungsmodus.

    
user965097 05.03.2012 18:02
quelle
0

Ein Ansatz zum Verkleinern eines 200x200 -Bildes auf, sagen wir 100x100 , wäre, jedes zweite Pixel entlang jeder Reihe und Spalte zu nehmen. Ich überlasse es Ihnen, Ihren eigenen Code für die Verkleinerung auf eine Größe zu rollen, die nicht die Originalgröße dividiert. Und ich gebe keine Garantie für die Eignung dieses Ansatzes für Ihr Problem.

    
High Performance Mark 05.03.2012 17:16
quelle