رؤية التوت بي الروبوت: خريطة العمق

الصورة

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



خريطة العمق من كاميرا واحدة.



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

الصورة

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

ماذا سنعمل على



تم أخذ صورة Raspbian Wheezy كقاعدة ، تم تثبيت Python 2.7 و OpenCV 2.4 ، حسنًا ، الحزم المطلوبة للأشياء الصغيرة - matplotlib ، numpy وغيرها. يتم وضع جميع الأنواع ورابط إلى الصورة النهائية للبطاقة في نهاية المقالة. يمكن العثور على وصف النصوص في شكل دروس على موقع المشروع

تحضير صورة لبناء خريطة عمق



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

البرنامج النصي الأول - محاذاة الكاميرا



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



ما هو المثير للاهتمام في رمز النص الأول
  • – , cv.imshow() , . , . , , .
  • – , .. . «» , camera.hflip = True



البرنامج النصي الثاني - نحصل على زوج ستيريو "نظيف"



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



ما هو مثير للاهتمام في رمز النص الثاني
  • , , cv2.rectangle(). , , . , , Enter .
  • , . , .
  • JSON. , , .
  • . , , , . , ./src . . pf_1280_720.txt – , .
  • , . . :
    loadImagePath = ""
    # loadImagePath = "./src/scene_1280x720_1.png"



السيناريو الثالث - سلسلة من الصور للمعايرة



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



ما هو مثير للاهتمام في كود البرنامج النصي الثالث
  • . , . , , «» . , – , . camera.capture () , use_video_port=True.
  • – camera.annotate_text() . 5 – .
  • -, , ./src



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

البرنامج النصي 4 - قطع الصور على أزواج ستيريو



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

مثال على العمل ورابط لمصادر النص الرابع


الشيء الأكثر إثارة للاهتمام هو المعايرة ، النص الخامس


يغذي نص المعايرة جميع أزواج الاستريو من المجلد ./src إلى وظيفة المعايرة ويغرق في التفكير. بعد عمله الصعب (لـ 15 صورة 1280x720 على التوت الأول يستغرق حوالي 5 دقائق) ، يأخذ آخر زوج استريو ، "يصحح" الصور (يصحح) ويعرض الإصدارات المصححة بالفعل التي يمكنك من خلالها بناء خريطة عمق.
إليك ما يبدو عليه البرنامج النصي في العمل:



ما هو مثير للاهتمام في رمز النص الخامس
  • StereoVision. , , , «» .
  • , . . «» , ,
  • calibrator.add_corners((imgLeft, imgRight), True)
    True False – , .



"حدث خطأ ما."


هناك أوقات تكون فيها نتائج المعايرة غير متوقعة.
فيما يلي بضعة أمثلة مذهلة:

خريطة التفاوت السيئة

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


إليك ما يبدو عليه زوج الاستريو "الثابت" مع نتائج المعايرة الجيدة:

الصورة

البرنامج النصي 6 - المحاولة الأولى لبناء خريطة عمق


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

الصورة

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

فيما يلي مصادر البرنامج النصي السادس

البرنامج النصي 7 - خريطة متعمقة مع إعدادات متقدمة


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



بعد تحديد المعلمات ، يحفظ البرنامج النصي بواسطة الزر حفظ النتيجة إلى ملف 3dmap_set.txt بتنسيق JSON.

ما هو المثير للاهتمام في كود البرنامج النصي السابع
  • 7-
  • . , - , .
  • , . , numOfDisparities 16, . update(val), . numOfDisparities 65.57 64. , .
  • matplotlib , .



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

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

ماذا نريد ان نراه؟


حسنًا ، ربما تكون إحدى أهم النقاط هي تعديل "طول النظر" لجهازنا. عند إعداد خريطة العمق ، عادة ما أضع شيئًا واحدًا على مسافة حوالي 30 سم ، والثاني في متر ، والباقي مترين. وعند إعداد أول معلمتين (minDisparity و numOfDisparities) في البرنامج النصي السابع ، أحقق ما يلي:
  • أقرب جسم (30 سم) - أحمر
  • الكائن في نصف متر - أصفر أو أخضر
  • كائنات 2-3 متر - أخضر أو ​​أزرق فاتح

ونتيجة لذلك ، حصلنا على نظام تم تكوينه للتعرف على منطقة "بالقرب" من العوائق في دائرة نصف قطرها 5-10 أمتار.

العمل بالفيديو على الطاير - النصي 8 ، النهائي


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



ما هو المثير للاهتمام في كود البرنامج النصي الثامن
– . , , overlay. , :

  • Overlay R, G B, - . grayscale
  • disparity_color = cv2.applyColorMap(disparity_grayscale, cv2.COLORMAP_JET)
  • overlay RGB, BGR – cv2.cvtColor()
  • Overlay 16. 16 — .



في السباق من أجل السرعة


لذا ، تم إجراء القياس الأول على Raspberry الأول باستخدام معالج أحادي النواة.
- 4 ثوان - بناء خريطة على صورة 1280x720 هذا كثير.
- 2.5 ثانية - على Raspberry Pi 2 ، أفضل بالفعل.
أظهر التحليل أنه في هذه الحالة ، يتم استخدام نواة واحدة فقط على التوت الثاني. فوضى! لقد قمت بإعادة إنشاء OpenCV باستخدام مكتبة موازية TBB.
- 1.5 ثانية - إطلاق على التوت الثاني باستخدام متعدد النواة. في الواقع ، اتضح أنه يتم استخدام نواتين فقط - وهذا لا يزال يتعين العبث به. اتضح أنني لم أواجه هذه المشكلة فقط ، لذلك لا يزال هناك مجال للتحرك.
استنادًا إلى الخوارزمية ، يجب أن تعتمد سرعة التشغيل بشكل خطي على حجم البيانات المعالجة. لذلك ، إذا قمت بتقليل الدقة بمقدار مرتين ، فيجب أن يعمل كل شيء نظريًا بشكل أسرع 4 مرات.
- 0.3 ثانية ، أو حوالي 3-4 إطارات في الثانية - بدقة نصف مخفضة تبلغ 640 × 360. تم تأكيد النظرية.

خطط أخرى


بادئ ذي بدء ، كنت أرغب في الحصول على أقصى استفادة من multicore من التوت الثاني. سوف ألقي نظرة فاحصة على مصادر وظيفة StereoBM وأحاول أن أفهم لماذا لا يسير العمل على طول الطريق.

تعد المرحلة التالية بمزيد من المغامرة - هذا هو استخدام GPU التوت لتسرع الحسابات.
يتم رسم ثلاثة مسارات محتملة هنا:



إذا كانت لديك خبرة في العمل مع TBB لـ Raspberry OpenCV ، أو كنت تتعامل مع الترميز لوحدات معالجة رسومات التوت ، فسأكون ممتنًا للحصول على تلميحات إضافية . تمكنت من العثور على عدد غير قليل من التطورات الجاهزة لسبب واحد بسيط - التوت مع كاميرتين أمر نادر الحدوث. إذا قمت بتوصيل كاميرتي ويب عبر USB ، فإن المكابح الكبيرة تأتي ، ولا يمكن سوى Raspberry Pi Compute العمل مع كاميرتين أصليتين ، والتي تحتاج أيضًا إلى لوحة ضخمة مع الأربطة والمحولات.

روابط مفيدة:


مخطوطات العمل:

إعداد OpenCV و Python على التوت:

مكتبة StereoVision:

عمل GPU

حسنًا ، مقال مثير للاهتمام حول " التعرف على الصور ، لا تحتاج إلى التعرف على الصور "

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


All Articles