Wie kann ich tun, qualitativ hochwertige Skalierung eines Bildes?

stimmen
18

Ich schreibe einige Code ein 32 Bit RGBA Bild in C / C ++ zu skalieren. Ich habe ein paar Versuche geschrieben, dass etwas erfolgreich gewesen sind, aber sie sind langsam und vor allem die Qualität der Größe Bild ist nicht akzeptabel.

Ich vergleichen das gleiche Bild von OpenGL skaliert (dh meiner Grafikkarte) und meine Routine und es ist Meilen voneinander entfernt in der Qualität. Ich habe Google Code gesucht, abgekocht Quelle Bäume von allem, was ich dachte, dass etwas Licht (SDL, Allegro, wxWidgets, CxImage, GD, ImageMagick, etc.), aber in der Regel ihren Code entweder verworren und zerstreut alle über den Ort oder durchlöchert Assembler und wenig oder keine Kommentare. Ich habe auch mehrere Artikel auf Wikipedia und anderswo, und ich bin einfach nicht finden, eine klare Erklärung dessen, was ich brauche lesen. Ich verstehe die grundlegenden Konzepte der Interpolation und Sampling, aber ich bin zu kämpfen, den Algorithmus richtig zu machen. Ich mag nicht für eine Routine auf einer externe Bibliothek verlassen und zu ihrem Bildformat konvertieren und zurück. Außerdem würde ich gerne wissen, wie es mir auf jeden Fall zu tun. :)

Ich habe eine ähnliche Frage vor auf Stack-Überlauf fragt gesehen, aber es war auf diese Weise nicht wirklich beantwortet, aber ich hoffe, es ist jemand da draußen, die in der richtigen Richtung schubsen mir helfen können. zeigen Sie mir vielleicht auf einige Artikel oder Pseudo-Code ... alles mir zu helfen, zu lernen und tun.

Hier ist, was ich suche:

  1. Kein Assembler (Ich bin sehr portablen Code für mehrere Prozessortypen zu schreiben).
  2. Keine Abhängigkeiten von externen Bibliotheken.
  3. Ich bin in erster Linie mit Verkleinerung, sondern auch später eine Scale-up-Routine schreiben muß.
  4. Qualität des Ergebnisses und die Klarheit des Algorithmus am wichtigsten ist (ich kann es optimieren später).

Meine Routine nimmt im Wesentlichen die folgende Form:

DrawScaled(uint32 *src, uint32 *dst, 
      src_x, src_y, src_w, src_h, 
      dst_x, dst_y, dst_w, dst_h );

Vielen Dank!

UPDATE: Um zu klären, ich brauche etwas weiter fortgeschritten als eine Schachtel Resampling für Downscaling , die das Bild verwischt zu viel. Ich vermute , was ich will eine Art bikubisch ist (oder andere) Filter, der etwas umgekehrt zu einer bikubischen Upscaling - Algorithmus ist (dh jedes Zielpixel aus allen beitragenden Quellenpixeln kombiniert mit einem Gewichtungsalgorithmus berechnet wird , die Dinge scharf hält.

Beispiel

Hier ist ein Beispiel dafür, was ich aus dem wxWidgets BoxResample Algorithmus immer vs. was ich will auf einem 256x256 Bitmap 55x55 skaliert.

  • www.free_image_hosting.net/uploads/1a25434e0b.png

Und schlussendlich:

  • www.free_image_hosting.net/uploads/eec3065e2f.png

das ursprüngliche 256x256 Bild

Veröffentlicht am 09/12/2008 um 16:05
quelle vom benutzer
In anderen Sprachen...                            


11 antworten

stimmen
2

Nun, da ich das Originalbild zu sehen, denke ich, dass OpenGL einen Nächster-Nachbar-Algorithmus verwendet. Nicht nur ist es die einfachste Art und Weise, um die Größe, aber es ist auch die schnellste. Der einzige Nachteil ist, dass es sehr rau aussieht, wenn es irgendein Detail in Ihrem ursprünglichen Bild.

Die Idee ist, gleichmäßigen Abständen Proben aus dem Originalbild zu übernehmen; in Ihrem Fall 55 von 256, oder einem von 4,6545. Gleich um die Zahl zu erhalten, das Pixel zu wählen.

Beantwortet am 10/12/2008 um 04:20
quelle vom benutzer

stimmen
2

Ist es möglich, dass OpenGL die Skalierung in der Vektor Domäne tut? Wenn ja, gibt es keine Möglichkeit, dass jeder Pixel-basierte Skalierung in der Nähe davon in Qualität sein wird. Dies ist der große Vorteil von Vektor-basierten Bildern.

Der bicubic Algorithmus kann für Schärfe gegen Artefakte abgestimmt werden - ich versuche, eine Verbindung zu finden, die ich es in bearbeiten würde, wenn ich es tue.

Edit: Es war die Mitchell-Netravali Arbeit, die ich dachte, die an der Unterseite dieses Link verwiesen wird:

http://www.cg.tuwien.ac.at/~theussl/DA/node11.html

Sie könnten auch in aussehen Lanczos-Filter als Alternative zu Bikubisch.

Beantwortet am 09/12/2008 um 19:00
quelle vom benutzer

stimmen
2

Ein recht einfacher und anständiger Algorithmus Bilder sampeln ist Bicubic Interpolation , hat wikipedia allein die alle Informationen , die Sie brauchen dies umgesetzt werden.

Beantwortet am 09/12/2008 um 16:21
quelle vom benutzer

stimmen
2

Ich habe die wxWidgets Implementierung recht einfach zu modifizieren, wie erforderlich gefunden. Es ist alles C ++, so dass keine Probleme mit dort Portabilität. Der einzige Unterschied besteht darin, dass ihre Implementierung arbeitet mit unsigned char-Arrays (die wir finden die einfachste Art und Weise mit Bildern irgendwie umgehen sein) mit einer Byte-Reihenfolge von RGB und der Alpha-Komponente in einem separaten Array.

Wenn Sie auf die „src / common / image.cpp“ Datei im WxWidgets Quellbaum verweisen gibt es eine Abwärts Sampler-Funktion, die eine Box Sampling-Methode verwendet „wxImage :: ResampleBox“ und eine Up-Scaler-Funktion namens „wxImage :: ResampleBicubic“.

Beantwortet am 09/12/2008 um 16:18
quelle vom benutzer

stimmen
1

Es klingt wie Sie , was wirklich schwer zu verstehen, die die diskrete ist -> kontinuierliche -> Flow diskrete beteiligt richtig ein Bild Resampling. Ein guter Tech - Bericht, den Sie geben können , die Einsicht in diese helfen , die Sie brauchen , ist Alvy Ray Smith Ein Pixel ist nicht ein kleiner Platz .

Beantwortet am 09/12/2008 um 20:41
quelle vom benutzer

stimmen
1

Intel hat IPP-Bibliotheken, die für Intel-Familie Prozessoren optimierte High-Speed-Interpolation Algorithmen bereitzustellen. Es ist sehr gut, aber es ist aber nicht frei. Schauen Sie sich auf den folgenden Link:

Intel IPP

Beantwortet am 09/12/2008 um 17:33
quelle vom benutzer

stimmen
1

Ein Sammelartikel aus unserem geliebten host: Bessere Bild Verkleinerung , die relativen Qualitäten verschiedenen Algorithmen zu diskutieren (und es Links zu anderen Codeproject Artikeln).

Beantwortet am 09/12/2008 um 17:12
quelle vom benutzer

stimmen
1

Versuchen Sie, die mit Adobe Allgemeinbildbibliothek ( http://opensource.adobe.com/wiki/display/gil/Downloads ) , wenn Sie etwas bereit wollen und nicht nur ein Algorithmus.


Auszug aus: http://www.catenary.com/howto/enlarge.html#c

Vergrößern oder verkleinern - der C-Quellcode Benötigt Victor Bildverarbeitungsbibliothek für 32-Bit-Windows v 5.3 oder höher.


int enlarge_or_reduce(imgdes *image1)
{
   imgdes timage;
   int dx, dy, rcode, pct = 83; // 83% percent of original size

   // Allocate space for the new image
   dx = (int)(((long)(image1->endx - image1->stx + 1)) * pct / 100);
   dy = (int)(((long)(image1->endy - image1->sty + 1)) * pct / 100);
   if((rcode = allocimage(&timage, dx, dy,
      image1->bmh->biBitCount)) == NO_ERROR) {
      // Resize Image into timage
      if((rcode = resizeex(image1, &timage, 1)) == NO_ERROR) {
         // Success, free source image
         freeimage(image1);
         // Assign timage to image1
         copyimgdes(&timage, image1);
         }
      else // Error in resizing image, release timage memory
         freeimage(&timage);
      }
   return(rcode);
}

Dieses Beispiel paßt einen Bildbereich und ersetzt das Originalbild mit dem neuen Bild.

Beantwortet am 09/12/2008 um 16:44
quelle vom benutzer

Beantwortet am 09/12/2008 um 16:37
quelle vom benutzer

stimmen
0

Als Follow - up erzielte Jeremy Rudd diesen Artikel oben. Es implementiert zwei Pass Redimensionierung gefiltert. Die Quellen sind C # , aber es sieht genug klar , dass ich kann portiert es zu versuchen. Ich fand sehr ähnlich C - Code gestern , dass es sehr viel schwieriger zu verstehen war (sehr schlecht Variablennamen). Ich habe es zu sortieren-of-Arbeit, aber es war sehr langsam und nicht zu guten Ergebnissen , die mich dazu gebracht zu glauben , ein Fehler in meiner Anpassung war. Ich kann mehr Glück haben es von Grund auf mit diesem als Referenz zu schreiben, die ich versuchen werde.

Aber wenn man bedenkt, wie die beiden Pass Algorithmus funktioniert Ich frage mich, ob es nicht ein schneller Weg, es zu tun, vielleicht sogar in einem Durchgang?

Beantwortet am 09/12/2008 um 21:07
quelle vom benutzer

stimmen
0

Werfen Sie einen Blick auf ImageMagick , die alle Arten von Umskalierungs Filter tut.

Beantwortet am 09/12/2008 um 18:57
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more