2011-01-13 17 views
8

क्या एक विशिष्ट बिटरेट पर जेपीईजी एन्कोड करने का कोई तरीका है?जेपीईजी संपीड़न के लिए बिटरेट निर्दिष्ट कैसे करें?

वर्तमान में, मैं ImageMagick के convert उपयोग कर रहा हूँ:

convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg 

गुणवत्ता के साथ बिटरेट बढ़ जाती है, लेकिन यह गैर रेखीय है। मैं स्पष्ट रूप से बिटरेट को नियंत्रित करना चाहता हूं। यह सटीक नहीं होना चाहिए, लेकिन मैं इसे उचित रूप से बंद करना चाहता हूं (निर्दिष्ट सेटिंग के 0.1 बीपीपी कहें)।

क्या कोई एन्कोडर है जो छवियों को किसी विशेष बिट-दर पर एन्कोड करने की अनुमति देता है? यह imagemagick होने की ज़रूरत नहीं है, मैं जो भी काम करता हूं (अधिमानतः लिनक्स पर) ले जाऊंगा।

ऐसा करने का एक गूंगा तरीका -quality पैरामीटर पर आंशिक मानों के साथ खेलना होगा जब तक कि लक्ष्य बिटरेट के करीब कुछ न आए, लेकिन मैं एक और अधिक सुरुचिपूर्ण समाधान की उम्मीद कर रहा हूं।

संपादित करें:

तो मैं ऊब गया और बातें त्वरित (लेकिन बेवकूफ) तरीके से करना का फैसला किया।

alt text

तो बिटरेट में बदलाव के लिए काफी ठीक है:

alt text

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

सुझाव: लूप के लिए निकालें, खोज के साथ प्रतिस्थापित करें। मुझे विश्वास नहीं है कि कोई भी एक जेपीईजी 1-> ~ 30 या ~ 99-> 100 की श्रेणियों में गुणवत्ता कारकों के साथ एन्कोड किया होगा। आप विभिन्न ग्राफ प्रकारों के लिए अपना ग्राफ भी बना सकते हैं और खोज के लिए बेहतर प्रारंभिक प्रारंभ बिंदु तैयार कर सकते हैं। यह सब बहुत ही मूर्ख है क्योंकि आप गुणवत्ता पर भी विचार नहीं करते हैं (जैसे पीएसएनआर); एक अलग क्वांटिज़ेशन टेबल चुनने से आपको वह बिटरेट मिल सकता है जो आप चाहते हैं लेकिन बहुत अधिक गुणवत्ता। – koan

+0

सुझाव के लिए धन्यवाद। खोज कोड की दक्षता में सुधार करेगी, लेकिन फिलहाल यह वास्तव में चिंता का कारण नहीं है क्योंकि यह जितना तेज़ है उतना तेज़ है। आप गुणवत्ता के बारे में सही हैं - सबसे सामान्य लोगों को उस कम गुणवत्ता वाले जेपीईजी की आवश्यकता नहीं होती है क्योंकि वे कचरे की तरह दिखते हैं। हालांकि, मैं खुद छवियों में दिलचस्पी ले रहा हूं, क्योंकि मैं छवियों में गिरावट का अध्ययन कर रहा हूं। क्वांटिज़ेशन टेबल के बारे में बिंदु दिलचस्प है - मुझे लगता है कि मैं इसे देख लूंगा। इसे शायद ओपनसीवी से दूर जाने और ijg जैसे कुछ का उपयोग करने की आवश्यकता होगी, क्योंकि ओपनसीवी क्वांटिज़ेशन टेबल का पर्दाफाश नहीं कर रहा है। – misha

उत्तर

4

मैं बहुत काम पता है एक JPEG एनकोडर के उत्पादन में बिटरेट (जैसे 1st paper; 2nd paper) को नियंत्रित करने पर मौजूद हैं, और कहा कि ऐसे नियंत्रण जेपीईजी 2000 में मौजूद हैं। दुर्भाग्यवश, मुझे यकीन नहीं है कि किसी भी प्रकार का बिटरेट नियंत्रण जेपीईजी के लिए मानकीकृत है, या सामान्य पुस्तकालयों में लागू किया गया है।उदाहरण के लिए आपको किसी प्रकार की बाइनरी खोज का उपयोग करके अपनी खुद की विधि को कोड करना पड़ सकता है ...

लेकिन फिर, मुझे गलत हो सकता है - और यदि ऐसा है, तो मुझे ऐसी लाइब्रेरी के बारे में सुनना अच्छा लगेगा।

जिज्ञासा से बाहर, आप किस भाषा का उपयोग कर रहे हैं?

+0

उत्तर और लिंक के लिए धन्यवाद। दुर्भाग्य से, मेरी यूनी स्प्रिंगरलिंक की सदस्यता नहीं लेती है, लेकिन मुझे दूसरे पेपर का एक पठन था। अपने प्रश्न का उत्तर देने के लिए: गंभीर छवि कार्य के लिए मैं सी/सी ++ का उपयोग करता हूं, लेकिन यदि मैं इसके लिए अपनी स्वयं की विधि कोडिंग समाप्त करता हूं, तो शायद मैं केवल पाइथन/बैश के कारण का उपयोग करूंगा क्योंकि मैं आलसी हूं। – misha

+0

और यह भी आसान तरीका होगा। वैसे भी - अगर आप इस विशेष समस्या के लिए एक अच्छे समाधान पर ठोकरें तो हमें बताएं :) – BlueCookie

+0

मैंने नमूना कोड के साथ प्रश्न अद्यतन किया। मैं इसे एक * अच्छा * समाधान नहीं कहूंगा लेकिन इस समय मेरे पास यही एकमात्र है। – misha

2

जेपीजी में बिटरेट-गुणवत्ता अनुपात सामग्री पर काफी निर्भर है। यदि आप एक विशिष्ट बिटरेट पर एन्कोड करना चाहते हैं, तो मेरा सुझाव है कि आप इसे दो पास करते हैं: 1. एक निश्चित गुणवत्ता कारक पर एन्कोड करें (आपके लक्षित बिटरेट के करीब बेहतर है, आपके ग्राफ़ पर आधारित हो सकता है) 2. इसके आकार के आधार पर , मूल को एक उच्च या निम्न गुणवत्ता पर फिर से कोड करें। फिर यह आपके ग्राफ या कुछ समान पर आधारित हो सकता है।

आप आवश्यक सटीक बिटरेट प्राप्त करने के लिए अनिश्चित काल तक अंतिम चरण भी दोहरा सकते हैं।

मैं इसे कई चरम मामलों, जैसे एक बहुत शोर/व्यस्त छवि, एक काला आयताकार, या एक चिकनी ढाल के साथ परीक्षण करता हूं।

संबंधित मुद्दे