عرض استريو منخفض الميزانية في سطور قليلة من التعليمات البرمجية (صورة مجسمة ، النقش ، مجسمة)

لقد حان عطلة نهاية أسبوع أخرى ، مما يعني أنني أكتب بضع أسطر أخرى من التعليمات البرمجية وأقوم بعمل توضيح أو اثنين. لقد أوضحت في المقالات السابقة كيفية تتبع الأشعة وحتى تفجير الأشياء . قد يفاجئك ذلك ، لكن رسومات الكمبيوتر سهلة للغاية: حتى بضع مئات من خطوط C ++ العارية يمكن أن تنتج بعض الصور المثيرة للغاية.

موضوع اليوم هو رؤية مجهر ، ونحن لن كسر حاجز 100 خطوط تفعل ذلك. نظرًا لأنه يمكننا رسم المشاهد ثلاثية الأبعاد ، سيكون من الحماقة تجاهل أزواج الاستريو ، لذا سنقوم اليوم بعمل شيء مثل هذا:




الجنون المطلق لمبدعي ماجيك كاربت لا يزال يضربني. بالنسبة لأولئك غير المدركين ، سمحت لك هذه اللعبة بإجراء تجسيد ثلاثي الأبعاد في وضع النقش والصور المجسمة من قائمة الإعدادات الرئيسية ! كان هذا وحشي بالنسبة لي.

المنظر


لنبدأ. للبدء ، ما الذي يجعل جهاز رؤيتنا يدرك العمق في الأشياء؟ هناك مصطلح ذكي "المنظر". دعنا نركز على الشاشة. كل ما هو موجود داخل الطائرة من الشاشة يتم تسجيله بواسطة دماغنا ككائن واحد. ولكن إذا كانت ذبابة تطير بين أعيننا والشاشة ، فإن الدماغ ينظر إليها ككائنين. كما سيتم مضاعفة العنكبوت خلف الشاشة.



دماغنا فعال جداً في تحليل الصور المختلفة قليلاً. يستخدم التباين المجهر للحصول على معلومات حول العمق من الصور ثنائية الأبعاد القادمة من شبكية العين باستخدام التعقيم . حسنًا ، اربط الكلمات الكبيرة ودعنا نرسم الصور فقط!

دعنا نتخيل أن شاشتنا هي نافذة على العالم الافتراضي :)



مهمتنا هي رسم صورتين لما نراه من خلال "النافذة" ، واحدة لكل عين. على الصورة أعلاه "شطيرة" حمراء زرقاء. دعنا ننسى الآن كيفية إيصال هذه الصور إلى عقولنا ، في هذه المرحلة نحتاج فقط إلى حفظ ملفين منفصلين. على وجه الخصوص ، أريد أن أعرف كيفية الحصول على هذه الصور باستخدام جهاز raytracer الصغير .

لنفترض أن الزاوية لا تتغير وهي متجه (0،0 ، -1). لنفترض أنه يمكننا نقل الكاميرا إلى المنطقة الواقعة بين العينين ، لكن ماذا بعد؟ تفصيل صغير واحد: إن وجهة نظر العرض من خلال "النافذة" الخاصة بنا غير متماثلة. لكن جهاز تتبع الشعاع لدينا لا يمكن أن يؤدي إلا إلى إحباط متماثل:



وماذا نحن الآن؟ الغش :)

يمكننا تقديم صور أوسع قليلاً مما نحتاج إليه ، ثم نقطع الأجزاء الإضافية:



النقش


أعتقد أننا قمنا بتغطية آلية التقديم الأساسية ، والآن نتناول مسألة توصيل الصورة إلى عقولنا. أبسط طريقة هي هذا النوع من النظارات:



نحن نصنع تجسيدين رمزيين ونعين صورًا لليمين واليسار للقنوات الحمراء والزرقاء على التوالي. هذا هو ما حصلنا عليه:



يقطع الزجاج الأحمر قناة واحدة ، بينما يقطع الزجاج الأزرق الآخر. مجتمعة ، تحصل العينان على صورة مختلفة ونتصورها ثلاثية الأبعاد. فيما يلي التعديلات على الالتزام الرئيسي من tinyraytracer. تتضمن التغييرات وضع الكاميرا لكل من مجموعة العيون والقنوات.

تُظهر ميزة "النقش" إحدى أقدم الطرق لمشاهدة صور الاستريو (التي يتم إنشاؤها بواسطة الكمبيوتر). لديها الكثير من الجوانب السلبية ، على سبيل المثال ، انتقال اللون السيئ. ولكن من ناحية أخرى ، من السهل جدًا إنشاء هذه في المنزل.

إذا لم يكن لديك مترجم على جهاز الكمبيوتر الخاص بك ، فهذا ليس مشكلة. إذا كان لديك حساب guithub ، يمكنك عرض وتعديل وتشغيل الرمز (كذا!) بنقرة واحدة في المتصفح الخاص بك.

فتح في gitpod

عندما تفتح هذا الرابط ، ينشئ gitpod جهازًا افتراضيًا لك ، ويطلق VS Code ، ويفتح محطة على الجهاز البعيد. في محفوظات الأوامر (انقر فوق وحدة التحكم واضغط على المفتاح لأعلى) ، هناك مجموعة كاملة من الأوامر التي تتيح لك ترجمة الشفرة وإطلاقها وفتح الصورة الناتجة.

مجسمة


مع تحول الهواتف الذكية إلى التيار الرئيسي ، تذكرنا حول اختراع القرن التاسع عشر الذي يسمى المجسم. قبل عامين اقترح Google استخدام عدستين (من المؤسف أنه يصعب إنشاؤها في المنزل ، فأنت تحتاج إلى شرائها) ، وقليلًا من الورق المقوى (متوفر في أي مكان) وهاتف ذكي (في جيبك) لإنشاء تصديق معقول نظارات الواقع الافتراضي



انهم الكثير على AliExpress وتكلفة مثل 3 دولارات للزوج. مقارنةً بنمط النقش ، ليس لدينا الكثير مما يجب فعله: ما عليك سوى التقاط صورتين ووضعهما جنبًا إلى جنب. ها هو الالتزام .



بالمعنى الدقيق للكلمة ، وفقًا للعدسة ، قد نحتاج إلى تصحيح تشويه العدسة ، لكنني لم أزعج ذلك ، حيث بدا جيدًا بصرف النظر عن ذلك. ولكن إذا احتجنا حقًا إلى تطبيق التشوه المسبق للبرميل الذي يعوض التشوه الطبيعي من العدسة ، فهذا ما يبدو عليه في هاتفي الذكي ونظارتي:



هنا هو الرابط gitpod:

فتح في gitpod

Autostereograms


وماذا نفعل إذا لم نرغب في استخدام أي معدات إضافية؟ ثم هناك خيار واحد فقط - التحديق. الصورة السابقة ، بصراحة ، كافية تمامًا للعرض المجسم ، فقط قم بعصر عينيك (إما عبور العينين أو تعليق الجدران عليها). إليك مخطط يوضح لنا كيفية مشاهدة الرسم التوضيحي السابق. يظهر خطان أحمران الصور كما تظهر في شبكية العين اليسرى ، خطان أزرقان - الشبكية اليمنى.



إذا ركزنا على الشاشة ، فستجمع أربع صور في صورتين. إذا عبرنا العينين ، أو ركزنا على كائن بعيد ، فمن الممكن إطعام الصور "الثلاثية" للمخ. تتداخل الصور المركزية ، مما يخلق تأثير ستيريو.

يستخدم الأشخاص المختلفون طرقًا مختلفة: على سبيل المثال ، لا أستطيع عبور عيني ، لكنني أعلقها بسهولة. من المهم أن يتم عرض الرسم التلقائي المصمم لطريقة معينة فقط بهذه الطريقة ، وإلا فلنحصل على خريطة عمق معكوسة (هل تتذكر المنظر الإيجابي والسلبي؟). المشكلة هي أنه من الصعب تجاوز العينين ، لذا فهو يعمل فقط على الصور الصغيرة. ولكن ماذا لو كنا نريد أكبر؟ دعونا التضحية بالألوان تماما والتركيز فقط على الجزء عمق الإدراك. إليكم الصورة التي نأمل الحصول عليها بحلول نهاية المقال:



هذا هو autostereogram جدار العينين. بالنسبة لأولئك الذين يفضلون الطريقة الأخرى ، إليك صورة لذلك . إذا لم تكن معتادًا على رسم الخرائط التلقائية ، فجرّب ظروفًا مختلفة: ملء الشاشة ، صورة أصغر ، سطوع ، ظلام. هدفنا هو حائط أعيننا بحيث تتداخل الشريحتان العموديتان القريبتان. أسهل شيء هو التركيز على الجزء العلوي الأيسر من الصورة ، لأنه سهل. أنا شخصياً أفتح الصورة بملء الشاشة. لا تنسَ إزالة مؤشر الماوس أيضًا!

لا تتوقف عند تأثير ثلاثي الأبعاد غير مكتمل. إذا كنت ترى أشكالًا دائرية غامضة ، وكان التأثير ثلاثي الأبعاد ضعيفًا ، فسيكون هذا الوهم غير مكتمل. من المفترض أن "تقفز" المجالات من الشاشة باتجاه المشاهد ، ويجب أن يكون التأثير مستقرًا ومستدامًا. يوجد في عملية التجسيم: عندما تحصل على صورة ثابتة ، يصبح أكثر تفصيلاً كلما طالت مدة مشاهدتها. كلما كانت العيون بعيدة عن الشاشة ، كلما كان تأثير إدراك العمق أكبر.

تم رسم هذا الرسم المجسم باستخدام طريقة مقترحة منذ 25 عامًا في هذه المقالة: " عرض صور ثلاثية الأبعاد: خوارزميات لصور مجسمة عشوائية أحادية الصورة ."

لنبدأ


نقطة الانطلاق لتقديم الصور التلقائية هي خريطة العمق (بما أننا نتخلى عن الألوان). يرسم هذا الالتزام الصورة التالية:



تحدد الطائرات الأقرب والأكثر عمقنا: أقصى نقطة في خريطتي لها عمق 0 ، بينما الأقرب لها بعمق 1.

المبادئ الأساسية


دعنا نقول عيوننا على مسافة د من الشاشة. نضع طائرتنا البعيدة (التخيلية) (z = 0) في نفس المسافة "خلف" الشاشة. نختار المتغير، ، الذي يحدد موقع الطائرة القريبة (z = 1) ، والذي سيكون على بعد fromd من المستوى البعيد. لرمز بلدي اخترت μ = ⅓. بشكل عام ، يعيش "عالمنا" بأكمله على مسافة من d-μd إلى d وراء الشاشة. دعنا نقول أننا نعرف المسافة بين العينين (بالبكسل ، لقد اخترت 400 بكسل):



إذا نظرنا إلى النقطة الحمراء ، فيجب أن يكون للبيكسلتين باللون الأخضر نفس اللون في الصورة المجسمة. كيفية حساب المسافة بينهما؟ سهل إذا كانت النقطة الحالية المسقطة لها عمق z ، فإن المنظر المقسوم على المسافة بين العينين يساوي الكسر بين الأعماق المقابلة: p / e = (d-dμz) / (2d-dμz). بالمناسبة ، لاحظ أن d مبسّط ولا يظهر في أي مكان آخر! ثم p / e = (1-μz) / (2-μz) ، وهذا يعني أن المنظر يساوي p = e * (1-μz) / (2-μz) بكسل.

الفكرة الرئيسية وراء autostereogram هي: نحن نذهب إلى خريطة العمق بأكملها ، ولكل قيمة عمق نقرر أي بكسل سيكون له نفس اللون ونضعه في نظامنا الخاص بالقيود. ثم نبدأ من الصورة العشوائية ونحاول تلبية جميع القيود التي وضعناها سابقًا.

تحضير الصورة المصدر


نحن هنا نعد الصورة التي سيتم تقييدها لاحقًا بقيود المنظر. إليك الالتزام ، وهو يرسم هذا:



لاحظ أن الألوان عشوائية في معظمها ، بصرف النظر عن القناة الحمراء حيث أضع rand () * sin لإنشاء نمط دوري. الشرائط متباعدة بمقدار 200 بكسل ، والتي (تعطى μ = 1/3 و e = 400) الحد الأقصى لقيمة المنظر في عالمنا (المستوى البعيد). النموذج ليس ضروريًا تقنيًا ، لكنه سيساعد على تركيز العينين.

التقديم التلقائي


في الواقع ، فإن الكود الكامل الذي يرسم الرسم التلقائي يبدو كالتالي:

int parallax(const float z) { const float eye_separation = 400.; // interpupillary distance in pixels const float mu = .33; // if the far plane is a distance D behind the screen, then the near plane is a distance mu*D in front of the far plane return static_cast<int>(eye_separation*((1.-z*mu)/(2.-z*mu))+.5); } size_t uf_find(std::vector<size_t> &same, size_t x) { return same[x]==x ? x : uf_find(same, same[x]); } void uf_union(std::vector<size_t> &same, size_t x, size_t y) { if ((x=uf_find(same, x)) != (y=uf_find(same, y))) same[x] = y; } int main() { [...] for (size_t j=0; j<height; j++) { // autostereogram rendering loop std::vector<size_t> same(width); std::iota(same.begin(), same.end(), 0); // initialize the union-find data structure (same[i]=i) for (size_t i=0; i<width; i++) { // put the constraints int par = parallax(zbuffer[i+j*width]); int left = i - par/2; int right = left + par; // works better than i+par/2 for odd values of par if (left>=0 && right<(int)width) uf_union(same, left, right); // left and right pixels will have the same color } for (size_t i=0; i<width; i++) { // resolve the constraints size_t root = uf_find(same, i); for (size_t c=0; c<3; c++) framebuffer[(i+j*width)*3+c] = framebuffer[(root+j*width)*3+c]; } } [...] 


ها هي الالتزام ، تمنحك الدالة int parallax (const float z) المسافة بين البكسل من نفس اللون لقيمة العمق الحالية. نجعل الخط المجسّم سطراً سطراً ، نظرًا لأن الخطوط مستقلة عن بعضها البعض (ليس لدينا مناظير رأسية). الحلقة الرئيسية تتكرر ببساطة عبر كل سطر ؛ في كل مرة يبدأ بمجموعة غير محدودة من البكسل ، ثم يضيف قيدًا لكل مساواة لكل بكسل. في النهاية ، فإنه يعطينا عددًا معينًا من مجموعات ذات وحدات البكسل الملونة نفسها. على سبيل المثال ، يجب أن تنتهي وحدات البكسل ذات الفهارس إلى اليسار واليمين بالتطابق.

كيفية تخزين هذه المجموعة من القيود؟ إن أبسط طريقة هي بنية بيانات العثور على الاتحاد . لن أخوض في التفاصيل ، فقط اذهب إلى ويكيبيديا ، إنه حرفي ثلاثة سطور من التعليمات البرمجية. النقطة الأساسية هي أنه لكل كتلة هناك "الجذر" بكسل مسؤولة عن الكتلة. يحتفظ بكسل الجذر باللون الأولي ، ويتم تحديث جميع وحدات البكسل الأخرى في الكتلة:

  for (size_t i=0; i<width; i++) { // resolve the constraints size_t root = uf_find(same, i); for (size_t c=0; c<3; c++) framebuffer[(i+j*width)*3+c] = framebuffer[(root+j*width)*3+c]; } 


فتح في gitpod

الخاتمة


هذا كل شيء حقا. عشرون سطرًا من الشفرة و autostereogram الخاصة بنا جاهزة لك لكسر عينيك عليها. بالمناسبة ، إذا حاولنا بجد بما فيه الكفاية ، فمن الممكن نقل معلومات الألوان.

لم أكن أغطي أنظمة مجسمة أخرى مثل الأنظمة ثلاثية الأبعاد المستقطبة ، لأنها أغلى بكثير. إذا فاتني شيء ما ، فلا تتردد في تصحيح لي!

Source: https://habr.com/ru/post/ar441014/


All Articles