क्या एक विशिष्ट बिटरेट पर जेपीईजी एन्कोड करने का कोई तरीका है?जेपीईजी संपीड़न के लिए बिटरेट निर्दिष्ट कैसे करें?
वर्तमान में, मैं ImageMagick के convert
उपयोग कर रहा हूँ:
convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg
गुणवत्ता के साथ बिटरेट बढ़ जाती है, लेकिन यह गैर रेखीय है। मैं स्पष्ट रूप से बिटरेट को नियंत्रित करना चाहता हूं। यह सटीक नहीं होना चाहिए, लेकिन मैं इसे उचित रूप से बंद करना चाहता हूं (निर्दिष्ट सेटिंग के 0.1 बीपीपी कहें)।
क्या कोई एन्कोडर है जो छवियों को किसी विशेष बिट-दर पर एन्कोड करने की अनुमति देता है? यह imagemagick होने की ज़रूरत नहीं है, मैं जो भी काम करता हूं (अधिमानतः लिनक्स पर) ले जाऊंगा।
ऐसा करने का एक गूंगा तरीका -quality
पैरामीटर पर आंशिक मानों के साथ खेलना होगा जब तक कि लक्ष्य बिटरेट के करीब कुछ न आए, लेकिन मैं एक और अधिक सुरुचिपूर्ण समाधान की उम्मीद कर रहा हूं।
संपादित करें:
तो मैं ऊब गया और बातें त्वरित (लेकिन बेवकूफ) तरीके से करना का फैसला किया।
तो बिटरेट में बदलाव के लिए काफी ठीक है:
Btw, यहाँ छवि मैं प्रयोग किया जाता है:
सबसे पहले, यहाँ ImageMagick के -quality
का ग्राफ बिटरेट बनाम है कम गुणवत्ता वाले मान, लेकिन लगभग 80 के बाद मोटे हो जाते हैं।
कुछ लक्ष्य बिटरेट पर किसी छवि को एन्कोड करने के लिए यहां कुछ नमूना कोड दिए गए हैं। मैंने OpenCV का उपयोग किया क्योंकि यह इन-मेमोरी जेपीईजी एन्कोडिंग (कोई I/O आवश्यक नहीं) के लिए अनुमति देता है। जबकि मैं मूल रूप से इसे पायथन के साथ नकल करने जा रहा था, दुर्भाग्यवश पाइथन ओपनसीवी रैपर इन-मेमोरी एन्कोडिंग कार्यक्षमता का पर्दाफाश नहीं करते हैं। तो मैंने इसे सी ++ में लिखा था।
आखिरकार, मैं लक्ष्य बिटरेट के करीब पहुंचने के लिए गुणवत्ता पर रैखिक इंटरपोलेशन का उपयोग करने के बारे में सोच रहा था, लेकिन cv::imencode
केवल पूर्णांक पैरामीटर स्वीकार करता है, इसलिए गैर-पूर्णांक जेपीईजी गुणवत्ता सेट करना संभव नहीं है। ओपनसीवी और इमेजमैजिक के बीच गुणवत्ता का स्तर कुछ हद तक अलग दिखता है, इसलिए ओपनसीवी से इंटरपोलेटेड गुणवत्ता पैरामीटर लेना और छविमैजिक के convert
में उपयोग करना अच्छा काम नहीं करता है।
इसका मतलब है कि आउटपुट बिटरेट लक्ष्य बिटरेट के बराबर नहीं है, खासकर उच्च बिटरेट (> 1) पर। लेकिन यह करीब है।
क्या कोई बेहतर कुछ सुझा सकता है?
कोड:
#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;
}
संकलित करें और रन का उपयोग कर:
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
[email protected]:~/co/cpp$ ./jpeg-bitrate.out Lenna-gray.png test.jpeg 0.53
wrote test.jpeg at 88% quality, 0.55bpp
सुझाव: लूप के लिए निकालें, खोज के साथ प्रतिस्थापित करें। मुझे विश्वास नहीं है कि कोई भी एक जेपीईजी 1-> ~ 30 या ~ 99-> 100 की श्रेणियों में गुणवत्ता कारकों के साथ एन्कोड किया होगा। आप विभिन्न ग्राफ प्रकारों के लिए अपना ग्राफ भी बना सकते हैं और खोज के लिए बेहतर प्रारंभिक प्रारंभ बिंदु तैयार कर सकते हैं। यह सब बहुत ही मूर्ख है क्योंकि आप गुणवत्ता पर भी विचार नहीं करते हैं (जैसे पीएसएनआर); एक अलग क्वांटिज़ेशन टेबल चुनने से आपको वह बिटरेट मिल सकता है जो आप चाहते हैं लेकिन बहुत अधिक गुणवत्ता। – koan
सुझाव के लिए धन्यवाद। खोज कोड की दक्षता में सुधार करेगी, लेकिन फिलहाल यह वास्तव में चिंता का कारण नहीं है क्योंकि यह जितना तेज़ है उतना तेज़ है। आप गुणवत्ता के बारे में सही हैं - सबसे सामान्य लोगों को उस कम गुणवत्ता वाले जेपीईजी की आवश्यकता नहीं होती है क्योंकि वे कचरे की तरह दिखते हैं। हालांकि, मैं खुद छवियों में दिलचस्पी ले रहा हूं, क्योंकि मैं छवियों में गिरावट का अध्ययन कर रहा हूं। क्वांटिज़ेशन टेबल के बारे में बिंदु दिलचस्प है - मुझे लगता है कि मैं इसे देख लूंगा। इसे शायद ओपनसीवी से दूर जाने और ijg जैसे कुछ का उपयोग करने की आवश्यकता होगी, क्योंकि ओपनसीवी क्वांटिज़ेशन टेबल का पर्दाफाश नहीं कर रहा है। – misha