การสร้างบรรทัดฐานของจุดสุดยอดทางโปรแกรม


11

ฉันกำลังทำงานร่วมกับ Kinect face api มันมีอาร์เรย์ของจุดยอดและดัชนีสำหรับรูปสามเหลี่ยมซึ่งจะแสดงผลเพื่อสร้างภาพใบหน้า

จำนวนจุดยอดและคำสั่งของพวกเขาในอาร์เรย์รวมถึงดัชนีที่ได้รับจาก kinect นั้นไม่เปลี่ยนแปลงตลอดเวลา

อย่างไรก็ตาม api ไม่ได้ให้ข้อมูลเกี่ยวกับข้อมูล UV และบรรทัดฐานจุดสุดยอด

แอปพลิเคชันต้องการให้ฉันรักษาจุดสุดยอดตามที่ไคเนกต์กำหนดให้เป็นตำแหน่งของพวกเขาในการเปลี่ยนแปลงพื้นที่ 3 มิติตามการเคลื่อนไหวของใบหน้าดังนั้นการสร้างยูวีและบรรทัดฐานในซอฟต์แวร์แก้ไขแบบสามมิตินั้นเป็นปัญหา

ฉันสามารถสร้างรังสี UV โดยฉายตำแหน่งจุดยอดลงบนระนาบ 2D เนื่องจากมีจุดยอดน้อยมากบนระนาบเดียวกัน

อย่างไรก็ตามฉันไม่ทราบวิธีสร้างบรรทัดฐานจุดสุดยอดสำหรับตาข่ายโดยไม่มีจุดสุดยอดปกติตาข่ายใบหน้าดึงโดยไม่มีความลึกของคุณสมบัติจากก่อนหน้าแม้ว่าเงาจะมองเห็นได้เนื่องจากตำแหน่งจุดยอดถูกต้อง

ฉันเข้าใจว่าเนื่องจากไม่มีบรรทัดฐานของจุดสุดยอดแสงจะไม่ทำงานอย่างถูกต้องกับมันและด้วยเหตุนี้ตาข่ายที่ไม่มีสีซีดจึงดูเหมือนตอนนี้

ดังนั้นฉันจะสร้างบรรทัดฐานจุดสุดยอดได้อย่างไรเมื่อทั้งหมดที่ฉันมีเพียงแค่ตำแหน่งจุดสุดยอดและดัชนีของจุดยอดเพื่อสร้างรูปสามเหลี่ยมออกมาจากมัน?


n = (v1 - v0) x (v2 - v0) โดยที่ v0, v1 และ v2 เป็นจุดยอดของใบหน้า (สามเหลี่ยม) ที่เป็นปัญหา คำสั่งซื้อคือ importan ทำให้เป็นมาตรฐานถ้าคุณต้องการจริงๆ (และxข้ามผลิตภัณฑ์)
3Dave

คำตอบ:


14

การคำนวณแบบปกติจากตำแหน่งจุดสุดยอดนั้นค่อนข้างง่ายโดยใช้เวกเตอร์ครอสโปรดัค

สินค้าข้ามของสองเวกเตอร์และ (ข้อสังเกตหรือบางครั้ง ) เป็นแนวตั้งฉากเวกเตอร์และความยาวกับมุมระหว่างและVทิศทางของเวกเตอร์จะขึ้นอยู่กับคำสั่งของการคูณ:คือด้านตรงข้ามของ (ทั้งสองทิศทางตั้งฉากกับระนาบ)uvu×vuvuv||u×v||=||u||||v||sin(θ)θuvu×vv×u

หากคุณไม่คุ้นเคยกับผลิตภัณฑ์กากบาทฉันขอเชิญคุณอ่านและทำความคุ้นเคยกับมัน เรื่องธรรมดานั้นดูเหมือนจะง่าย

บรรทัดฐานการแรเงาแบบแบน

ถ้าคุณมีรูปสามเหลี่ยม ,เป็นเวกเตอร์ตั้งฉากกับสามเหลี่ยมและมีความยาวเป็นสัดส่วนกับพื้นที่ของมัน เนื่องจากปกติคือเวกเตอร์หน่วยตั้งฉากกับระนาบของสามเหลี่ยมคุณจึงได้ค่าปกติด้วย:ABCAB×AC

N=AB×AC||AB×AC||

ในรหัสนี้จะมีลักษณะn = normalize(cross(b-a, c-a))เช่น เพียงแค่ใช้สิ่งนี้กับใบหน้าของคุณและคุณจะมีบรรทัดฐานต่อใบหน้า

For each triangle ABC
    n := normalize(cross(B-A, C-A))
    A.n := n
    B.n := n
    C.n := n

โปรดทราบว่าสิ่งนี้ถือว่าจุดยอดจะไม่ถูกแชร์ระหว่างรูปสามเหลี่ยม ฉันไม่คุ้นเคยกับ Kinect API มีความเป็นไปได้ค่อนข้างมากที่พวกเขาจะแบ่งปันซึ่งในกรณีนี้คุณจะต้องทำซ้ำหรือย้ายไปยังโซลูชันถัดไป:

บรรทัดฐานการแรเงาเรียบ

หลังจากส่องสว่างด้วยการคำนวณตามปกติข้างต้นคุณจะสังเกตเห็นว่ามีขอบสามเหลี่ยมชัดเจน หากสิ่งนี้ไม่เป็นที่พึงปรารถนาคุณสามารถคำนวณนอร์มธรรมดาได้โดยคำนึงถึงใบหน้าทั้งหมดที่มีจุดยอดเดียวกัน

ความคิดคือว่าถ้ายอดเดียวกันจะใช้ร่วมกันโดยสามสามเหลี่ยม ,และตัวอย่างเช่นปกติจะเป็นค่าเฉลี่ยของ ,และN3นอกจากนี้หากเป็นรูปสามเหลี่ยมขนาดใหญ่และเป็นหนึ่งเล็ก ๆ ที่คุณอาจต้องการจะได้รับอิทธิพลมากขึ้นโดยกว่าโดยการN2T1T2T3NN1N2N3T1T2NN1N2

จำได้ว่าผลิตภัณฑ์ข้ามเป็นสัดส่วนกับพื้นที่ได้อย่างไร หากคุณเพิ่มผลิตภัณฑ์ครอสจากนั้นทำให้ผลรวมเป็นปกติมันจะทำผลรวมน้ำหนักที่เราต้องการ ดังนั้นอัลกอริทึมจะกลายเป็น:

For each vertex
    vertex.n := (0, 0, 0)

For each triangle ABC
    // compute the cross product and add it to each vertex
    p := cross(B-A, C-A)
    A.n += p
    B.n += p
    C.n += p

For each vertex
    vertex.n := normalize(vertex.n)

เทคนิคนี้จะอธิบายในรายละเอียดอีกต่อไปบทความนี้โดยIñigo Quilez: ฟื้นฟูฉลาดของตาข่าย


สำหรับข้อมูลเพิ่มเติมเกี่ยวกับมาตรฐานดูเพิ่มเติมที่:


ฉันจะให้เรื่องนี้โดยเร็วและกลับมาพร้อมกับผลลัพธ์
Allahjane

มันใช้งานได้ขอบคุณชายคนหนึ่งซึ่งทำงานได้อย่างที่ฉันต้องการ
Allahjane

ดูผลลัพธ์ได้ที่นี่ก่อนที่i.gyazo.com/a314d1f7a0509788c272f83279c5077b.png และหลังi.gyazo.com/b879db7294d82a72b86cc4eaf0132a13.png
Allahjane

@ Allahjane: ดีใจที่ได้ยินว่ามันทำงานได้ดี :)
Julien Guertault
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.