Wie geben Sie die bitrate für die JPEG-Komprimierung?
Gibt es eine Möglichkeit zu codieren JPEG auf eine bestimmte bitrate?
Jetzt bin ich mit imagemagick ' s convert
:
convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg
Bitrate erhöht sich mit der Qualität, aber es ist nicht-linear. Ich will zur Steuerung der bitrate ausdrücklich. Es muss nicht um genau zu sein, aber ich will es halbwegs in der Nähe (innerhalb von, sagen wir 0.1 bpp der angegebenen Einstellung).
Gibt es encoder gibt, erlaubt es, Bilder kodiert werden, auf eine bestimmte bit-rate? Es muss nicht sein, imagemagick, ich nehm, was funktioniert (vorzugsweise unter Linux).
Eine dumme Art und Weise, dies zu tun wäre, um zu spielen, um mit Bruchzahlen zu den -quality
parameter, bis etwas in der Nähe der Ziel-bitrate rauskommt, aber ich hoffe auf eine elegantere Lösung.
EDIT:
Also habe ich gelangweilt und beschlossen, Dinge zu tun, die eine schnelle (aber dumme) Weise.
Ersten, hier eine Grafik von imagemagick ist -quality
vs bitrate:
BTW, hier ist das Bild, das ich verwendet habe:
Damit die änderung in der bitrate ist ziemlich gut für eine niedrigere Qualität-Werte, wird aber grob nach etwa 80.
Hier einige Beispiel-code zu Kodieren eines Bildes bei einigen Ziel-bitrate. Ich verwendete OpenCV-Ursache, die es ermöglicht in-memory-JPEG-Kodierung (keine I/O erforderlich). Während ich ursprünglich wollte, zu verhöhnen, diese mit Python, leider sind die Python-OpenCV-Wrapper don ' T setzen Sie den in-memory-Codierung-Funktionalität. So habe ich es geschrieben in C++.
Schließlich, ich dachte die lineare interpolation zu verwenden, die auf die Qualität zu bekommen, näher an die Ziel-bitrate, aber da cv::imencode
akzeptiert nur integer-Parameter, es ist nicht möglich, eine nicht-integer-JPEG-Qualität. Die Qualität Skala zwischen OpenCV und imagemagick scheint, unterscheiden sich auch etwas, so dass die Einnahme der interpolierte Qualität parameter aus OpenCV und mit imagemagick ' s convert
hat nicht gut funktioniert.
Dies bedeutet, dass die Ausgabe-bitrate ist nicht gleich der Ziel-bitrate, vor allem bei höheren Bitraten ( > 1). Aber es ist in der Nähe.
Kann jemand empfehlen, etwas besser?
Code:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <assert.h>
#include <vector>
using cv::Mat;
using std::vector;
#define IMENCODE_FMT ".jpeg"
#define QUALITY_UBOUND 101
#define BITS_PER_BYTE 8
int
main(int argc, char **argv)
{
if (argc != 4)
{
fprintf(stderr, "usage: %s in.png out.jpeg bpp\n", argv[0]);
return 1;
}
char *fname_in = argv[1];
char *fname_out = argv[2];
float target;
sscanf(argv[3], "%f", &target);
Mat orig = cv::imread(fname_in);
int pixels = orig.size().width * orig.size().height * orig.channels();
vector<unsigned char> buf;
vector<int> params = vector<int>(2);
params[0] = CV_IMWRITE_JPEG_QUALITY;
int q;
double bpp = 0.0;
for (q = 1; q < QUALITY_UBOUND; ++q)
{
params[1] = q;
cv::imencode(IMENCODE_FMT, orig, buf, params);
bpp = (double)buf.size() * BITS_PER_BYTE /pixels;
if (bpp > target)
break;
}
cv::imwrite(fname_out, orig, params);
printf("wrote %s at %d%% quality, %.2fbpp\n", fname_out, q, bpp);
return 0;
}
Kompilieren und ausführen mit:
g++ -c -Wall -ggdb -I../c -I../blur `pkg-config --cflags opencv` -Wno-write-strings jpeg-bitrate.cpp -o jpeg-bitrate.o
g++ -I../c `pkg-config --cflags opencv` `pkg-config --libs opencv` -lboost_filesystem jpeg-bitrate.o -o jpeg-bitrate.out
rm jpeg-bitrate.o
misha@misha-desktop:~/co/cpp$ ./jpeg-bitrate.out Lenna-gray.png test.jpeg 0.53
wrote test.jpeg at 88% quality, 0.55bpp
- Vorschlag: Entfernen der for-Schleife ersetzen mit Suche. Ich kann nicht glauben, dass jemand möchte ein JPEG-codiert-mit den Qualitätsfaktoren in den Bereichen von 1->~30 oder ~99->100. Man könnte auch erstellen Sie Ihr Diagramm für eine Vielzahl von verschiedenen Bild-Typen und erarbeiten für Sie eine bessere Ausbildung Startpunkt für die Suche. Das ist alles sehr naiv, weil Sie denken gar nicht Qualität (z.B. PSNR); die Wahl einer anderen Quantisierungs-Tabelle erhalten Sie in der bitrate, wie Sie möchten, aber eine viel höhere Qualität.
- Danke für die Anregung. Die Suche würde sich verbessern, die Effizienz des Codes, aber im moment ist es nicht wirklich ein Problem verursachen, es ist schnell genug, wie es ist. Ihre hast Recht in Bezug auf Qualität-die meisten normalen Leute nicht brauchen, die JPEG-Bilder der niedrigen Qualität verursachen Sie sehen aus wie Müll. Allerdings habe ich selbst interessiere mich für solche Bilder, wie ich studiere Bild Erniedrigungen. Der Punkt über die Quantisierungstabellen ist interessant -- ich denke, ich werde das prüfen. Es wird wahrscheinlich erfordern eine Abkehr von OpenCV und etwas wie ijg, Ursache OpenCV scheint nicht verfügbar zu machen Quantisierungstabellen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich kenne eine Menge Arbeit gibt, die auf die Steuerung der Ausgabe-bitrate des JPEG-encoder (z.B. 1. Papier ; 2. Papier), und dass solche Kontrollen existieren in JPEG2000. Leider, ich bin nicht sicher, dass jede Art von bitrate control ist eine standardisierte JPEG -, oder umgesetzt in gemeinsamen Bibliotheken. Sie müssen möglicherweise code Ihre eigene Methode, mit einer Art binären Suche zum Beispiel...
Aber wieder, ich kann mich irren - und wenn ja, ich würde gerne hören, über eine solche Bibliothek.
Nur aus Neugier, welche Sprache verwenden Sie ?
Den bitrate-Qualität-Verhältnis in JPG ist ganz abhängig vom Inhalt. Wenn du encodieren willst, bei einer bestimmten bitrate, ich schlage vor, Sie tun es zwei Durchgänge:
1. Codieren an einem festen Faktor für die Qualität der (näher an Ihr Ziel-bitrate besser ist, könnte auf der Grundlage Ihrer Grafik)
2. Basierend auf seiner Größe, neu codieren das original in einer größeren oder niedriger Qualität. Dies kann wieder basierend auf Ihrem Diagramm oder etwas ähnliches.
Könnte man auch wiederholen Sie den letzten Schritt auf unbestimmte Zeit zu bekommen, die GENAU die bitrate, die Sie brauchen.
Ich würde testen Sie dies mit verschiedenen extremen Fällen, wie eine sehr laute/gebucht-Bild, ein Schwarzes Rechteck, oder einen weichen Verlauf.