क्या क्यूबिक लैग्रेग इंटरपोलेशन टैंसर उत्पाद बाइसिक्यूबल इंटरपोलेशन के समान है?


11

मैं अभी 4x4 निकटतम पिक्सल का नमूना लेकर कुछ प्रक्षेपित बनावट नमूने को कार्यान्वित करता हूं, फिर y अक्ष पर Lagrange प्रक्षेप का उपयोग करने के लिए चार मान प्राप्त करने के लिए एक्स अक्ष पर लैग्रेग प्रक्षेप कर रहा हूं।

क्या यह बाइबिक प्रक्षेप के समान है या यह अलग है? या वहाँ विभिन्न प्रकार के बाइबिक प्रक्षेप हैं, और यह उनमें से सिर्फ एक है शायद?

वेबलॉग Shadertoy कार्यान्वयन यहां और प्रासंगिक GLSL (WebGL) कोड नीचे: https://www.shadertoy.com/view/MSSX

धन्यवाद!

float c_textureSize = 64.0;

float c_onePixel = 1.0 / c_textureSize;
float c_twoPixels = 2.0 / c_textureSize;

float c_x0 = -1.0;
float c_x1 =  0.0;
float c_x2 =  1.0;
float c_x3 =  2.0;

//=======================================================================================
vec3 CubicLagrange (vec3 A, vec3 B, vec3 C, vec3 D, float t)
{
    return
        A * 
        (
            (t - c_x1) / (c_x0 - c_x1) * 
            (t - c_x2) / (c_x0 - c_x2) *
            (t - c_x3) / (c_x0 - c_x3)
        ) +
        B * 
        (
            (t - c_x0) / (c_x1 - c_x0) * 
            (t - c_x2) / (c_x1 - c_x2) *
            (t - c_x3) / (c_x1 - c_x3)
        ) +
        C * 
        (
            (t - c_x0) / (c_x2 - c_x0) * 
            (t - c_x1) / (c_x2 - c_x1) *
            (t - c_x3) / (c_x2 - c_x3)
        ) +       
        D * 
        (
            (t - c_x0) / (c_x3 - c_x0) * 
            (t - c_x1) / (c_x3 - c_x1) *
            (t - c_x2) / (c_x3 - c_x2)
        );
}

//=======================================================================================
vec3 BicubicTextureSample (vec2 P)
{
    vec2 pixel = P * c_textureSize + 0.5;

    vec2 frac = fract(pixel);
    pixel = floor(pixel) / c_textureSize - vec2(c_onePixel/2.0);

    vec3 C00 = texture2D(iChannel0, pixel + vec2(-c_onePixel ,-c_onePixel)).rgb;
    vec3 C10 = texture2D(iChannel0, pixel + vec2( 0.0        ,-c_onePixel)).rgb;
    vec3 C20 = texture2D(iChannel0, pixel + vec2( c_onePixel ,-c_onePixel)).rgb;
    vec3 C30 = texture2D(iChannel0, pixel + vec2( c_twoPixels,-c_onePixel)).rgb;

    vec3 C01 = texture2D(iChannel0, pixel + vec2(-c_onePixel , 0.0)).rgb;
    vec3 C11 = texture2D(iChannel0, pixel + vec2( 0.0        , 0.0)).rgb;
    vec3 C21 = texture2D(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;
    vec3 C31 = texture2D(iChannel0, pixel + vec2( c_twoPixels, 0.0)).rgb;    

    vec3 C02 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_onePixel)).rgb;
    vec3 C12 = texture2D(iChannel0, pixel + vec2( 0.0        , c_onePixel)).rgb;
    vec3 C22 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;
    vec3 C32 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_onePixel)).rgb;    

    vec3 C03 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_twoPixels)).rgb;
    vec3 C13 = texture2D(iChannel0, pixel + vec2( 0.0        , c_twoPixels)).rgb;
    vec3 C23 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_twoPixels)).rgb;
    vec3 C33 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_twoPixels)).rgb;    

    vec3 CP0X = CubicLagrange(C00, C10, C20, C30, frac.x);
    vec3 CP1X = CubicLagrange(C01, C11, C21, C31, frac.x);
    vec3 CP2X = CubicLagrange(C02, C12, C22, C32, frac.x);
    vec3 CP3X = CubicLagrange(C03, C13, C23, C33, frac.x);

    return CubicLagrange(CP0X, CP1X, CP2X, CP3X, frac.y);
}

2
आप संबंधित shader कोड को बिट्रोट के मामले में यहाँ पोस्ट कर सकते हैं, नहीं?
जूजा

1
हमें shader कोड के लिए कुछ प्रीटियर कोड मार्कअप होना चाहिए, अगर मैं किसी ने मुझे नहीं हराया है तो मैं मेटा पर पोस्ट करूँगा!
एलन वोल्फ

क्या हमारे सिंटैक्स हाइलाइटिंग द्वारा कवर की गई भाषाओं की सूची में एक विशिष्ट शेडर भाषा उपलब्ध नहीं है?
ट्राइकोप्लाक्स

मुझे यकीन नहीं है। यह सिर्फ GLSL (सटीक होने के लिए वेबलॉग से!) है। मैंने कोड की प्रत्येक पंक्ति से पहले केवल 4 स्थान बनाए थे, निश्चित नहीं कि क्या इसे चिह्नित करने का एक बेहतर तरीका है ...
एलन वुल्फ

जवाबों:


8

यह पता चला है कि नहीं, जबकि आप bicubic बनावट नमूने के लिए bicubic Lagrange interpolation का उपयोग कर सकते हैं, यह उच्चतम गुणवत्ता विकल्प नहीं है, और शायद वास्तव में इसका उपयोग करने की संभावना नहीं है।

क्यूबिक हेर्माइट स्प्लीन नौकरी के लिए एक बेहतर उपकरण है।

लैग्रेंज प्रक्षेप डेटा बिंदुओं से गुजरने वाली एक वक्र बनाता है, इस प्रकार C0 निरंतरता को संरक्षित करता है, लेकिन हेर्माइट स्प्लिन डेटा बिंदुओं से गुजरते हुए किनारों पर डेरिवेटिव को संरक्षित करता है, इस प्रकार C1 निरंतरता को संरक्षित करता है और बहुत बेहतर दिखता है।

इस सवाल में क्यूबिक हेर्माइट स्प्लिन पर कुछ बेहतरीन जानकारी है: /signals/18265/bicubic-interpolation

यहाँ प्रश्न में पोस्ट किए गए कोड का क्यूबिक हर्माइट संस्करण है:

//=======================================================================================
vec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)
{
    float t2 = t*t;
    float t3 = t*t*t;
    vec3 a = -A/2.0 + (3.0*B)/2.0 - (3.0*C)/2.0 + D/2.0;
    vec3 b = A - (5.0*B)/2.0 + 2.0*C - D / 2.0;
    vec3 c = -A/2.0 + C/2.0;
    vec3 d = B;

    return a*t3 + b*t2 + c*t + d;
}

//=======================================================================================
vec3 BicubicHermiteTextureSample (vec2 P)
{
    vec2 pixel = P * c_textureSize + 0.5;

    vec2 frac = fract(pixel);
    pixel = floor(pixel) / c_textureSize - vec2(c_onePixel/2.0);

    vec3 C00 = texture2D(iChannel0, pixel + vec2(-c_onePixel ,-c_onePixel)).rgb;
    vec3 C10 = texture2D(iChannel0, pixel + vec2( 0.0        ,-c_onePixel)).rgb;
    vec3 C20 = texture2D(iChannel0, pixel + vec2( c_onePixel ,-c_onePixel)).rgb;
    vec3 C30 = texture2D(iChannel0, pixel + vec2( c_twoPixels,-c_onePixel)).rgb;

    vec3 C01 = texture2D(iChannel0, pixel + vec2(-c_onePixel , 0.0)).rgb;
    vec3 C11 = texture2D(iChannel0, pixel + vec2( 0.0        , 0.0)).rgb;
    vec3 C21 = texture2D(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;
    vec3 C31 = texture2D(iChannel0, pixel + vec2( c_twoPixels, 0.0)).rgb;    

    vec3 C02 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_onePixel)).rgb;
    vec3 C12 = texture2D(iChannel0, pixel + vec2( 0.0        , c_onePixel)).rgb;
    vec3 C22 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;
    vec3 C32 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_onePixel)).rgb;    

    vec3 C03 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_twoPixels)).rgb;
    vec3 C13 = texture2D(iChannel0, pixel + vec2( 0.0        , c_twoPixels)).rgb;
    vec3 C23 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_twoPixels)).rgb;
    vec3 C33 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_twoPixels)).rgb;    

    vec3 CP0X = CubicHermite(C00, C10, C20, C30, frac.x);
    vec3 CP1X = CubicHermite(C01, C11, C21, C31, frac.x);
    vec3 CP2X = CubicHermite(C02, C12, C22, C32, frac.x);
    vec3 CP3X = CubicHermite(C03, C13, C23, C33, frac.x);

    return CubicHermite(CP0X, CP1X, CP2X, CP3X, frac.y);
}

यहाँ नमूने के तरीकों के बीच अंतर दिखाती एक तस्वीर है। बाएं से दाएं: निकटतम पड़ोसी, बिलिनियर, लाग्रेंज बाइक्यूबिक, हर्माइट बीकुबिक

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


हालांकि सभी क्यूबिक स्प्लिन एक अर्थ में, समतुल्य हैं, लेकिन कैट्मुल-रोम स्प्लिन का उपयोग करना संभवतः वैचारिक रूप से आसान है। उदा। cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf
साइमन एफ

क्या आपको लगता है कि ताऊ पैरामीटर इस मामले में मदद करता है या बाधा डालता है? मैं गलत हो सकता हूं लेकिन मुझे ऐसा लगता है कि कैटमूल रोम बहुत "उपयोगकर्ता परिभाषित" (और ट्यून किया जाना चाहिए) है, जबकि हेर्माइट स्पलाइन सिर्फ उस डेटा से जानकारी का उपयोग करने का प्रयास करता है जो वहां है। ऐसा लगता है कि क्यूबिक हेर्माइट एक "जमीनी सच्चाई" के करीब है, जो मुझे लगता है कि एक आदर्श सिन फ़िल्टर की तरह होगा। हालांकि आपको क्या लगता है?
एलन वोल्फ 15

मैं यह नहीं देखता कि कैटमुल-रोम "उपयोगकर्ता परिभाषित" कैसे है। एक बार जब आपके पास 4 सन्निहित बिंदुओं का अनुक्रम होता है, P [i-1], P [i], P [i + 1], P [i + 2] (2D मामले के लिए 4x4) वक्र खंड P [i के बीच परिभाषित होता है ] और P [i + 1] और पड़ोसी खंडों के साथ C1 निरंतर है। ऑडियो के लिए एक sinc फिल्टर ठीक है लेकिन वीडियो नहीं। मिशेल और नेत्रावली देखें: cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/… IIRC कैटमुल -रोम फ़िल्टर के परिवार का एक विशेष मामला है जो वे प्रस्तावित करते हैं, लेकिन मुझे लगता है कि फ़िल्टर एक अनुमानित वक्र है इसलिए, सीआर के विपरीत, मूल बिंदुओं के माध्यम से नहीं जा सकता है।
साइमन एफ

यही कारण है कि वह hermite spline काम करता है सिवाय इसके कि कैटलम रोम स्पलाइन में एक अतिरिक्त पैरामीटर ताऊ (तनाव) है जो उपयोगकर्ता परिभाषित है। इसके अलावा, sinc वीडियो पर लागू होता है, DSP DSP है: P
एलन वोल्फ

मुझे स्वीकार करना चाहिए, मैंने पहले कभी कैटमुल रोम के साथ जुड़े तनाव पैरामीटर को नहीं देखा है, लेकिन फिर मैंने वास्तव में केवल फोली और वैन डैम (एट अल) के माध्यम से सीखा है या, कहें, वाट एंड वाट जो, एएफएआईसीआर, मेक ऐसा कोई उल्लेख नहीं है। वास्तव में, कहा जाता है कि, चार बाधाएं हैं - अर्थात वक्र को 2 बिंदुओं से गुजरना पड़ता है और उन बिंदुओं पर दो परिभाषित स्पर्श रेखाएं होती हैं और यह एक घन है - मैं थोड़ा नुकसान में हूं कि कैसे कोई है एक तनाव पैरामीटर का समर्थन करने के लिए स्वतंत्रता की अधिक डिग्री .... ** जब तक आप मतलब स्पर्शरेखा तराशा जा सकता है?
साइमन एफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.