ผลิตภัณฑ์ลูกบาศก์เมตริกซ์การแก้ไขเมตริกซ์เป็นแบบเดียวกับการแก้ไข bicubic หรือไม่?


11

ฉันเพิ่งใช้การสุ่มตัวอย่างการประมาณค่าพื้นผิวโดยการสุ่มพิกเซลที่ใกล้ที่สุด 4x4 แล้วทำการแก้ไขลากรองจ์ข้ามแกน x เพื่อรับค่าสี่ค่าเพื่อใช้การแก้ไขลากรองจ์บนแกน y

สิ่งนี้เหมือนกับการแก้ไขแบบ Bicubic หรือแตกต่างกันหรือไม่? หรือมีการแก้ไขต่าง ๆ bicubic และนี่เป็นเพียงหนึ่งในพวกเขาอาจ?

การใช้งาน Webgl Shadertoy ที่นี่และรหัส GLSL (WebGL) ที่เกี่ยวข้องด้านล่าง: https://www.shadertoy.com/view/MllSzX

ขอบคุณ!

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 ที่เกี่ยวข้องที่นี่ในกรณีของ bitrot ไม่ใช่
joojaa

1
เราควรมีมาร์กอัปโค้ดที่น่ารักกว่านี้สำหรับรหัส shader ฉันจะโพสต์บนเมตาถ้ามีคนไม่ได้ตีฉัน!
Alan Wolfe

นั่นเป็นภาษาเฉพาะส่วนหนึ่งที่ไม่สามารถใช้ได้ในรายการภาษาที่ครอบคลุมโดยการเน้นไวยากรณ์ของเราหรือไม่?
trichoplax

ฉันไม่แน่ใจ. เป็นเพียง GLSL (จาก webgl เป็นที่แน่นอน!) ผมก็ไม่ได้ 4 ช่องว่างก่อนแต่ละบรรทัดของรหัสไม่แน่ใจว่ามีวิธีที่ดีกว่าที่จะทำเครื่องหมายขึ้น ...
อลันวูล์ฟ

คำตอบ:


8

ปรากฎว่าไม่มีในขณะที่คุณสามารถใช้การแก้ไข Lagubic Lagrange สำหรับการสุ่มตัวอย่างพื้นผิว Bicubic มันไม่ใช่ตัวเลือกคุณภาพสูงสุดและอาจไม่น่าจะใช้จริง

ลูกบาศก์ hermite splines เป็นเครื่องมือที่ดีกว่าสำหรับงาน

การแก้ไขลากรองจ์จะทำให้โค้งที่ผ่านจุดข้อมูลดังนั้นการรักษาความต่อเนื่องของ C0 แต่ hermite splines รักษาอนุพันธ์ที่ขอบในขณะที่ยังผ่านจุดข้อมูลดังนั้นการรักษาต่อเนื่อง C1 และดูดีขึ้นมาก

คำถามนี้มีข้อมูลที่ยอดเยี่ยมเกี่ยวกับลูกบาศก์ hermite splines: /signals/18265/bicubic-interpolation

นี่คือรหัสลูกบาศก์ hermite รุ่นที่ฉันโพสต์ในคำถาม:

//=======================================================================================
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);
}

นี่คือภาพที่แสดงความแตกต่างระหว่างวิธีการสุ่มตัวอย่าง จากซ้ายไปขวา: เพื่อนบ้านที่ใกล้ที่สุด, Bilinear, Lagrange Bicubic, Hermite Bicubic

ป้อนคำอธิบายรูปภาพที่นี่


แม้ว่าทุกลูกบาศก์จะมีความเหมือนกัน แต่ก็อาจจะง่ายกว่าที่จะใช้ Spline Catmull-Rom เช่น cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf
Simon F

คุณคิดว่าพารามิเตอร์ tau ช่วยหรือเป็นอุปสรรคในกรณีนี้หรือไม่? ฉันอาจจะผิด แต่ฉันรู้สึกเหมือน catmull rom เป็น "ผู้ใช้กำหนด" (และต้องปรับ) ในขณะที่ hermite spline พยายามที่จะใช้ข้อมูลจากข้อมูลที่มี ดูเหมือนว่าลูกบาศก์ hermite นั้นอยู่ใกล้กับ "ความจริงภาคพื้นดิน" ซึ่งฉันคิดว่าน่าจะเป็นตัวกรอง sinc ในอุดมคติ คุณคิดอย่างไร
Alan Wolfe

ฉันไม่เห็นว่า Catmull-Rom เป็น "ผู้ใช้กำหนด" เมื่อคุณมีลำดับของจุดที่ต่อเนื่องกัน 4 จุด P [i-1], P [i], P [i + 1], P [i + 2] (4x4 สำหรับกรณี 2D) ส่วนโค้งจะถูกกำหนดระหว่าง P [i ] และ P [i + 1] และเป็น C1 ต่อเนื่องกับส่วนที่อยู่ใกล้เคียง ตัวกรอง sinc ใช้ได้ดีสำหรับเสียง แต่ไม่ใช่วิดีโอ ดู Mitchell & Netravali: cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/ … IIRC Catmull-Rom เป็นกรณีพิเศษของตระกูลตัวกรองที่พวกเขาเสนอ แต่ฉันคิดว่าตัวกรองนั้นเป็นเส้นโค้งที่ใกล้เคียงดังนั้น แตกต่างจาก CR อาจไม่ผ่านจุดเริ่มต้น
Simon F

นั่นเป็นวิธีที่เขา hermite spline ทำงานยกเว้น catmull rom spline มีพารามิเตอร์เพิ่มเติม tau (ความตึงเครียด) ที่ผู้ใช้กำหนด นอกจากนี้ sinc ใช้กับวิดีโอ DSP คือ DSP: P
Alan Wolfe

ฉันต้องยอมรับว่าฉันไม่เคยเห็นพารามิเตอร์ความตึงเครียดที่เกี่ยวข้องกับ Catmull Rom splines มาก่อน แต่จากนั้นฉันได้เรียนรู้จากพวกเขาผ่านทาง Foley & van Dam (et al) หรือพูดว่า Watt & Watt ซึ่ง AFAICR ทำ ไม่มีการเอ่ยถึงเรื่องนี้ ที่จริงแล้วต้องบอกว่าเนื่องจากมีข้อ จำกัด สี่ประการนั่นคือเส้นโค้งต้องผ่าน 2 คะแนนและมีแทนเจนต์ที่กำหนดสองอัน ** ที่จุดเหล่านั้นและมันเป็นลูกบาศก์ - ฉันสูญเสียนิดหน่อยว่ามีอะไรบ้าง มีอิสระมากขึ้นในการรองรับพารามิเตอร์ความตึง .... ** ถ้าคุณไม่ได้หมายความว่าสามารถปรับขนาดแทนเจนต์ได้?
Simon F
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.