शोरगुल को रोकने के लिए एक उचित तरीका क्या है?


9

रंग की गहराई को कम करते हुए और 2 बिट शोर (n =] 0.5,1.5 [और आउटपुट = फ्लोर (इनपुट * (2 ^ बिट्स -1) + एन)) के साथ, मूल्य सीमा के अंत (इनपुट 0.0 और 1.0) ) शोर कर रहे हैं। उन्हें ठोस रंग होना वांछनीय होगा।

उदाहरण: https://www.shadertoy.com/view/llsfz4

शोर ढाल (ऊपर shadertoy का स्क्रीनशॉट है, एक ढाल का चित्रण और दोनों छोर जो क्रमशः ठोस सफेद और काले रंग के होने चाहिए , लेकिन इसके बजाय शोर होते हैं)

समस्या को केवल मूल्य सीमा को संकुचित करके हल किया जा सकता है ताकि छोर हमेशा एकल मानों पर गोल हो जाएं। हालांकि यह एक हैक का थोड़ा सा लगता है, और मैं सोच रहा हूं कि क्या यह "ठीक से" लागू करने का कोई तरीका है?


किसी कारण से मेरे ब्राउज़र पर shadertoy नहीं चला। क्या आप प्रदर्शित करने के लिए एक / कुछ सरल छवि (ओं) को पोस्ट कर सकते हैं?
सिमोन एफ

1
यह n =] की तरह अधिक नहीं होना चाहिए - 1, 1 [?
जर्कोएल

@ जारकोल खैर फ्लोटिंग पॉइंट को पूर्णांक में परिवर्तित करने का सूत्र आउटपुट = फ्लोर (इनपुट * इंटमैक्स + एन) है, जहां एन = 0.5 बिना शोर के है, क्योंकि आप चाहते हैं (उदाहरण के लिए) = = 0.5 से गोल अप करने के लिए, लेकिन <0.5 नीचे। इसलिए शोर 0.5 पर "केंद्रित" है।
हॉटमुल्टॉमी

@SimonF ने shadertoy की छवि को जोड़ा
hotmultimedia 20:

1
ऐसा लगता है कि आप इसे राउंड करने के बजाय आउटपुट को रौंद रहे थे (जैसे कि GPUs करते हैं) - इसके बजाय गोलाई, आपको कम से कम उचित गोरे मिलते हैं : shadertoy.com/view/MlsfD7 (छवि: i.stack.imgad.com/kxQWl.png )
मिकेल गोज़ेल

जवाबों:


8

टीएल; डीआर: 2 * 1LSB त्रिकोणीय-पीडीएफ dithering clamping के कारण 0 और 1 पर edgecases में टूट जाता है। एक समाधान उन edgecases में एक 1bit वर्दी तक lerp है।

मैं एक दूसरे उत्तर को जोड़ रहा हूं, क्योंकि यह देखने से मैं मूल रूप से थोड़ा अधिक जटिल हो गया था। ऐसा प्रतीत होता है कि यह मुद्दा "TODO: क्लैम्पिंग" की आवश्यकता है? मेरे कोड में जब से मैं 2012 में सामान्यीकृत से त्रिकोणीय dithering में बदल गया ... अंत में इसे देखने के लिए अच्छा लगता है :) समाधान / पोस्ट के लिए पूर्ण कोड का उपयोग करें : https://www.shadertoy.com/view/llXfzS

सबसे पहले, यहां वह समस्या है जिसे हम देख रहे हैं, जब 2 * 1LSB त्रिकोणीय-पीडीएफ के साथ 3 बिट्स के लिए एक संकेत की मात्रा:

आउटपुट - अनिवार्य रूप से हॉटमुल्टोमिक्स ने क्या दिखाया।

इसके विपरीत बढ़ते हुए, प्रश्न में वर्णित प्रभाव स्पष्ट हो जाता है: एडगैसेस में आउटपुट काले / सफेद करने के लिए औसत नहीं है (और वास्तव में ऐसा करने से पहले 0/1 से परे अच्छी तरह से फैली हुई है)।

यहाँ छवि विवरण दर्ज करें

एक ग्राफ को देखने से थोड़ी अधिक जानकारी मिलती है:

यहाँ छवि विवरण दर्ज करें (ग्रे लाइन्स मार्क 0/1, ग्रे में भी जो सिग्नल हम आउटपुट की कोशिश कर रहे हैं, पीली-लाइन डीथर्ड / क्वांटीकृत आउटपुट का औसत है, लाल त्रुटि है (सिग्नल-एवरेज))।

दिलचस्प बात यह है कि सीमा पर न केवल औसत आउटपुट 0/1 है, बल्कि यह रैखिक (शोर के त्रिकोणीय पीडीएफ के कारण भी) नहीं है। निचले सिरे को देखते हुए, यह सहज ज्ञान युक्त बनाता है कि आउटपुट क्यों बदल जाता है: जैसे ही डिथर्ड सिग्नल नकारात्मक मानों को शामिल करना शुरू करता है, क्लैम्पिंग-ऑन-आउटपुट आउटपुट के निचले स्तरित भागों (यानी नकारात्मक मान) के मूल्य को बदलता है, जिससे औसत के मूल्य में वृद्धि। एक चित्रण क्रम में प्रतीत होता है (समान, सममित 2LSB dither, औसत अभी भी पीले रंग में)

यहाँ छवि विवरण दर्ज करें

अब, यदि हम केवल 1LSB सामान्यीकृत डार्स का उपयोग करते हैं, तो किनारों-मामलों में कोई समस्या नहीं है, लेकिन फिर निश्चित रूप से हम त्रिकोणीय डिटेरिंग के अच्छे गुणों को खो देते हैं (उदाहरण के लिए इस प्रस्तुति को देखें )।

यहाँ छवि विवरण दर्ज करें

ए (व्यावहारिक, अनुभवजन्य) समाधान (हैक) तो, [-0.5; 0.5] को वापस करने के लिए है [edgecase के लिए एक समान dithering):

float dithertri = (rnd.x + rnd.y - 1.0); //note: symmetric, triangular dither, [-1;1[
float dithernorm = rnd.x - 0.5; //note: symmetric, uniform dither [-0.5;0.5[

float sizt_lo = clamp( v/(0.5/7.0), 0.0, 1.0 );
float sizt_hi = 1.0 - clamp( (v-6.5/7.0)/(1.0-6.5/7.0), 0.0, 1.0 );

dither = lerp( dithernorm, dithertri, min(sizt_lo, sizt_hi) );

शेष सीमा के लिए त्रिकोणीय dithering बरकरार रखते हुए, जो edgecases को ठीक करता है:

यहाँ छवि विवरण दर्ज करें

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

EDIT
I को केवल संकेत को संपीड़ित करने पर, प्रश्न में दिए गए समाधान-सुझाव को कवर करना चाहिए। क्योंकि औसत edgecases में रैखिक नहीं है, बस इनपुट-सिग्नल को संपीड़ित करने से एक आदर्श परिणाम नहीं होता है - हालांकि यह समापन बिंदुओं को ठीक करता है: यहाँ छवि विवरण दर्ज करें

संदर्भ


यह आश्चर्यजनक है कि किनारों पर लार्प एक परिपूर्ण दिखने वाला परिणाम देता है। मैं कम से कम एक छोटे से विचलन की उम्मीद करूंगा: पी
एलन वोल्फ

हाँ, मैं सकारात्मक रूप से आश्चर्यचकित भी था :) मुझे विश्वास है कि यह काम करता है क्योंकि हम घोर-परिमाण को रैखिक रूप से घटा रहे हैं, उसी दर पर संकेत कम हो रहा है। तो फिर कम से कम पैमाने पर मेल खाता है ... लेकिन मैं मानता हूं कि यह दिलचस्प है कि सीधे वितरणों के सम्मिश्रण का कोई नकारात्मक साइड-इफेक्ट नहीं है।
मिकेल गज़ेल

@MikkelGjoel दुर्भाग्य से, आपके कोड में बग के कारण आपका विश्वास गलत है। आपने दोनों के लिए एक ही आरएनजी का उपयोग किया dithertriऔर dithernormएक स्वतंत्र के बजाय। एक बार जब आप सभी गणित के माध्यम से काम करते हैं और सभी शर्तों को रद्द करते हैं, तो आप पाएंगे कि आप बिलकुल भी दुबले नहीं हैं! इसके बजाय, कोड हार्ड कटऑफ की तरह काम करता है v < 0.5 / depth || v > 1 - 0.5/depth, तुरंत वहां समान वितरण पर स्विच करता है। ऐसा नहीं है कि यह आपके पास मौजूद अच्छे से दूर ले जाता है, यह सिर्फ अनावश्यक रूप से जटिल है। बग को ठीक करना वास्तव में बुरा है, आप इससे भी बदतर स्थिति में आ जाएंगे। बस एक हार्ड कटऑफ का उपयोग करें।
orlp

और भी गहरी खुदाई करने के बाद मैंने आपके shadertoy में एक और मुद्दा पाया है जहाँ आप नमूनों के दौरान गामा-सही नहीं करते हैं (आप sRGB अंतरिक्ष में औसत है जो रैखिक नहीं है)। यदि आप उचित रूप से गामा को संभालते हैं तो हम पाते हैं कि दुर्भाग्य से हम अभी तक नहीं हुए हैं। गामा सुधार से निपटने के लिए हमें अपने शोर को आकार देना चाहिए। यहाँ एक shadertoy मुद्दे को प्रदर्शित कर रहा है: shadertoy.com/view/3tf3Dn । मैंने चीजों की एक गुच्छा की कोशिश की है और इसे काम करने के लिए नहीं मिला है, इसलिए मैंने यहां एक प्रश्न पोस्ट किया है: computergraphics.stackexchange.com/questions/8793/…
orlp

3

मुझे यकीन नहीं है कि मैं आपके प्रश्न का पूरी तरह से उत्तर दे सकता हूं, लेकिन मैं कुछ विचार जोड़ूंगा और हो सकता है कि हम एक साथ उत्तर दे सकें :)

सबसे पहले, सवाल की नींव मेरे लिए थोड़ा अस्पष्ट है: जब आप हर दूसरे रंग में शोर करते हैं, तो आप इसे काला / सफेद साफ करने के लिए वांछनीय क्यों मानते हैं? पूरी तरह एकसमान शोर के साथ आपके मूल सिग्नल को डिटरिंग करने के बाद आदर्श परिणाम है। यदि ब्लैक एंड व्हाइट अलग-अलग हैं, तो आपका शोर सिग्नल-निर्भर हो जाता है (जो हालांकि ठीक हो सकता है, क्योंकि ऐसा होता है जहां रंगों को वैसे भी क्लैंप किया जाता है)।

उस ने कहा, ऐसी स्थितियां हैं, जहां या तो गोरे या अश्वेत में शोर होना एक मुद्दा है (मुझे यूजेस के बारे में पता नहीं है जिसके लिए एक साथ "साफ" होने के लिए काले और सफेद दोनों की आवश्यकता होती है): जब एक क्वाड के रूप में एक योज्य मिश्रित कण का प्रतिपादन किया जाता है एक बनावट, आप नहीं चाहते कि पूरे क्वाड में शोर जोड़ा जाए, क्योंकि यह बनावट के बाहर भी दिखाई देगा। एक समाधान शोर को ऑफसेट करना है, इसलिए जोड़ने के बजाय [-0.5; 1.5 [आप [-2.0 जोड़ें; 0.0] (यानी शोर के 2 ग्राम घटाना)। यह काफी अनुभवजन्य समाधान है, लेकिन मुझे अधिक सही दृष्टिकोण के बारे में पता नहीं है। इसके बारे में सोचकर, आप संभावित रूप से खोई हुई तीव्रता की भरपाई के लिए अपने संकेत को बढ़ाना चाहते हैं ...

कुछ हद तक, टिमोथी लोट्स ने स्पेक्ट्रम के कुछ हिस्सों में शोर को आकार देने पर एक जीडीसी से बात की, जहाँ स्पेक्ट्रम के उज्ज्वल अंत में शोर को कम करना: http://32ipi028l5q82yhj722248jj-wpengine.netdna-ssl.com/wp-wp- सामग्री / अपलोड / 2016/03 / GdcVdrLottes.pdf


(क्षमा करें, मैंने गलती से प्रवेश किया, और समय सीमा समाप्त हो गई है) संपादित करें उदाहरण में usecase उन स्थितियों में से एक है जहां यह मामला होगा: 3-बिट डिस्प्ले डिवाइस पर एक फ्लोटिंग पॉइंट ग्रेस्केल छवि प्रदान करना। यहाँ एलएसबी को बदलने से तीव्रता में बहुत परिवर्तन होता है। मैं यह समझने की कोशिश कर रहा हूं कि क्या वैल्यू रेंज को कंप्रेस करने के लिए एंड वैल्यू मैप को सॉलिड कलर्स में लाने का कोई "सही तरीका" है, एंड वैल्यू सैचुरेट है। और उस की गणितीय व्याख्या क्या है? उदाहरण सूत्र में, 1.0 का इनपुट मान आउटपुट का औसत 7 से उत्पन्न नहीं करता है, और यही मुझे परेशान करता है।
हॉटमुल्ट्रोमी

1

मैंने एक सरल कार्य के लिए त्रिकोणीय शोर के साथ मिखेल गोज़ेल के विचार को सरल बनाया है, जिसे केवल एक आरएनबी कॉल की आवश्यकता है। मैंने सभी अनावश्यक बिट्स को छीन लिया है, इसलिए यह बहुत पठनीय और समझने योग्य होना चाहिए कि क्या हो रहा है:

// Dithers and quantizes color value c in [0, 1] to the given color depth.
// It's expected that rng contains a uniform random variable on [0, 1].
uint dither_quantize(float c, uint depth, float rng) {
    float cmax = float(depth) - 1.0;
    float ci = c * cmax;

    float d;
    if (ci < 0.5 || ci >= cmax - 0.5) {
        // Uniform distribution on [-0.5, 0.5] for edges.
        d = rng - 0.5;
    } else {
        // Symmetric triangular distribution on [-1, 1].
        d = (rng < 0.5) ? sqrt(2.0 * rng) - 1.0 : 1.0 - sqrt(2.0 - 2.0*rng);
    }

    return uint(clamp(ci + d + 0.5, 0.0, cmax));
}

विचार और संदर्भ के लिए मैं आपको मिकेल गोज़ेल के उत्तर का उल्लेख करूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.