تم نشر هذه المقالة كجزء من مدونة علوم البيانات
المُقدّمة
مرحبا بالجميع! في حين أن cyberpunk لم يدخل حياتنا بعد كثيرًا ، والواجهات العصبية بعيدة كل البعد عن المثالية ، يمكن أن يصبح LiDAR المرحلة الأولى على طريق مستقبل المتلاعبين. لذلك ، من أجل عدم الشعور بالملل خلال العطلات ، قررت أن أتخيل قليلاً حول عناصر التحكم في جهاز الكمبيوتر ، ويفترض ، أي جهاز ، حتى الحفار ، أو سفينة الفضاء ، أو الطائرة بدون طيار ، أو الموقد.
الفكرة الرئيسية هي تحريك الماوس ، وليس تحريك اليد بأكملها ، ولكن فقط إصبع السبابة ، والذي سيسمح لك بالمرور عبر القائمة دون رفع يديك عن لوحة المفاتيح ، والضغط على الأزرار ، ومع مفاتيح الاختصار ، تتحول إلى النينجا لوحة المفاتيح الحقيقية! ماذا يحدث إذا أضفت إيماءات التمرير أو التمرير؟ أعتقد أنه ستكون هناك قنبلة! لكن حتى هذه اللحظة لا يزال يتعين علينا الانتظار بضع سنوات)
لنبدأ في تجميع النموذج الأولي الخاص بنا من مناور المستقبل
ماذا تحتاج:
-
الكاميرا مزودة بتقنية LiDAR Intel Realsense L515.
-
القدرة على البرمجة بلغة بيثون
-
فقط تذكر القليل من رياضيات المدرسة
-
تركيب للكاميرا على الشاشة ويعرف أيضا باسم ترايبود
نعلق الكاميرا على حامل ثلاثي القوائم مع AliExpress ، واتضح أنها مريحة للغاية وخفيفة الوزن ورخيصة)
نكتشف كيف وماذا نصنع نموذجًا أوليًا
هناك العديد من الأساليب لإنجاز هذه المهمة. يمكنك تدريب الكاشف أو تجزئة اليد بنفسك ، وقطع الصورة الناتجة عن اليد اليمنى ثم تطبيق هذا المستودع الرائع من بحث Facebook على الصورة ، والحصول على نتيجة ممتازة أو جعل الأمر أسهل.
لاستخدام مستودع أنابيب الوسائط ، بعد قراءة هذا الرابط, يمكنك أن تفهم أن هذا هو أحد أفضل الخيارات لهذا اليوم.
أولاً ، كل شيء موجود بالفعل خارج الصندوق - سيستغرق التثبيت والتشغيل 30 دقيقة ، مع مراعاة جميع المتطلبات الأساسية.
ثانيًا ، بفضل فريق التطوير القوي ، فهم لا يأخذون تقدير الوضع الفني في متناول اليد فحسب ، بل يوفرون أيضًا واجهة برمجة تطبيقات سهلة الفهم.
ثالثًا ، الشبكة جاهزة للتشغيل على وحدة المعالجة المركزية ، وبالتالي فإن عتبة الدخول في حدها الأدنى.
ربما سوف تسأل لماذا لم أتي إلى هنا ولم أستخدم مستودعات الفائزين في هذه المسابقة. في الواقع ، لقد درست حلهم بشيء من التفصيل ، فهم جاهزون تمامًا ، ولا توجد مجموعات من الملايين من الشبكات ، وما إلى ذلك. ولكن يبدو لي أن المشكلة الأكبر هي أنها تعمل مع الصور العميقة. نظرًا لأن هؤلاء أكاديميون ، لم يترددوا في تحويل جميع البيانات من خلال Matlab ، بالإضافة إلى أن القرار الذي تم فيه تصوير الأعماق بدا صغيرًا بالنسبة لي. قد يكون لهذا تأثير عميق على النتيجة. لذلك ، يبدو أن أسهل طريقة هي الحصول على النقاط الرئيسية في صورة RGB وأخذ القيمة على طول المحور Z في إطار العمق بواسطة إحداثيات XY. المهمة الآن ليست تحسين شيء ما كثيرًا ، لذلك سنفعله لأنه أسرع من وجهة نظر التطوير.
تذكر الرياضيات المدرسية
كما كتبت بالفعل ، من أجل الحصول على تنسيق النقطة حيث يجب أن يكون مؤشر الماوس ، نحتاج إلى بناء خط يمر عبر نقطتين رئيسيتين في كتائب الإصبع ، والعثور على نقطة تقاطع الخط والعلامة مستوى الشاشة.
تُظهر الصورة بشكل تخطيطي مستوى الشاشة والخط الذي يتقاطع معها. يمكنك إلقاء نظرة على الرياضيات هنا.
باستخدام نقطتين ، نحصل على تمثيل حدودي لخط مستقيم في الفضاء.
لن أركز كثيرًا على منهج الرياضيات المدرسي.
تركيب مكتبة للعمل بالكاميرا
ربما يكون هذا هو الجزء الأصعب من هذه الوظيفة. كما اتضح ، فإن برنامج الكاميرا الخاص بـ Ubuntu بدائي للغاية ، والحس الليبرالي مليء بكل أنواع الأخطاء ، ومواطن الخلل ، والرقصات باستخدام الدف.
حتى الآن ، لم أتمكن من التغلب على السلوك الغريب للكاميرا ، وأحيانًا لا يتم تحميل المعلمات عند بدء التشغيل.
الكاميرا تعمل مرة واحدة فقط بعد إعادة تشغيل الحاسب !!! ولكن هناك حل: قبل كل عملية إطلاق ، قم بإعادة ضبط الكاميرا للبرامج ، وأعد ضبط USB ، وربما يكون كل شيء على ما يرام. بالمناسبة ، بالنسبة لنظام التشغيل Windows 10 ، كل شيء على ما يرام هناك. من الغريب أن يتخيل المطورون روبوتات تعتمد على Windows =)
للحصول على معنى حقيقي في ظل Ubuntu 20 ، قم بما يلي:
sudo apt-get install libusb-1.0-0-dev ثم أعد تشغيل cmake و قم بالتثبيت. هنا is وصفة كاملة عملت For أنا: sudo apt-get install libusb-1.0-0-dev $ git clone https://github.com/IntelRealSense/librealsense.git $ cd librealsense / $ mkdir build && cd build
بعد التجميع من الفرز ، سيكون مستقرًا إلى حد ما. كشف شهر من التواصل مع الدعم الفني أنك بحاجة إلى تثبيت Ubuntu 16 أو تعاني. اخترتها بنفسك ، أنت تعرف ماذا.
نستمر في فهم تعقيدات الشبكة العصبية
الآن دعنا نرى مقطع فيديو آخر لعملية الإصبع والفأرة. يرجى ملاحظة أن المؤشر لا يمكن أن يقف في مكان واحد ، وكما كان ، فإنه يطفو حول النقطة المقصودة. في الوقت نفسه ، يمكنني توجيهها بسهولة إلى الكلمة التي أحتاجها ، ولكن مع وجود حرف ، يكون الأمر أكثر صعوبة ، ويجب أن أحرك المؤشر بعناية:
هذا ، كما تفهم ، ليس مصافحة يدي ، في أيام العطلات ، شربت كوبًا واحدًا فقط من New England DIPA =) كل شيء يتعلق بالتقلبات المستمرة للنقاط الرئيسية والإحداثيات Z بناءً على القيم التي تم الحصول عليها من الليدار.
دعونا نلقي نظرة فاحصة:
في SOTA الخاص بنا من أنبوب الوسائط ، هناك بالتأكيد تقلبات أقل ، لكنها موجودة أيضًا. كما اتضح ، فإنهم يكافحون مع هذا باستخدام prokid vaniya من خريطة الحرارة للإطار السابق في الإطار الحالي وشبكة القطار - إنه يوفر مزيدًا من الاستقرار ، ولكن ليس بنسبة 100 ٪.
يبدو لي أيضًا أن خصوصية العلامات تلعب دورًا. يكاد يكون من الممكن عمل نفس الترميز على مثل هذا العدد من الإطارات ، ناهيك عن حقيقة أن دقة الإطار مختلفة في كل مكان وليست كبيرة جدًا. كما أننا لا نرى وميض الضوء ، وهو على الأرجح غير ثابت بسبب فترات التشغيل المختلفة ومقدار التعرض للكاميرا. وتقوم الشبكة أيضًا بإرجاع شطيرة من خريطة الحرارة تساوي عدد النقاط الرئيسية على الشاشة ، وحجم هذا الموتر هو BxNx96x96 ، حيث N هو عدد النقاط الرئيسية ، وبالطبع بعد العتبة وتغيير الحجم إلى الأصل حجم الإطار ، نحصل على ما نحصل عليه (
مثال على عرض خريطة التمثيل اللوني:
مراجعة الكود
كل الكود موجود في هذا المستودع وهو قصير جدًا. دعنا نلقي نظرة على الملف الرئيسي ونرى الباقي بنفسك.
استيراد cv2 استيراد ميديابيب as mp استيراد نمباي as np استيراد com.pyautogui استيراد 2. pyrealsense2 as rs تبدأ من google.protobuf.json_format استيراد رسالة إلى ديكت تبدأ من mediapipe.python.solutions.drawing_utils استيراد _تطبيع_إلى_إحداثيات_البكسل تبدأ من بينبت استيراد لوحة المفاتيح تبدأ من utils.common استيراد get_filtered_values ، draw_cam_out ، get_right_index تبدأ من الاستخدامات. hard_reset استيراد مجموعة الأجهزة تبدأ من uses.set_options استيراد set_short_range pyautogui.FAILSAFE = False mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands # Hand Pose Estimation hands = mp_hands.Hands (max_num_hands = 2، min_detection_confidence = 0.9) صفر عند_الضغط(مفتاح): if المفتاح == keyboard.Key.ctrl: pyautogui.leftClick () if key == keyboard.Key.alt: pyautogui.rightClick () صفر الحصول على عمق_اللون(خط الأنابيب ، محاذاة ، تلوين): الإطارات = pipeline.wait_for_frames (timeout_ms = 15000) # انتظار إطار من الكاميرا align_frames = align.process (الإطارات) deep_frame = align_frames.get_depth_frame () color_frame = align_frames.get_color_frame () if ليس عمق_إطار or ليس لون_الإطار: عائد أعلى لا شيء ، لا شيء ، لا شيء deep_ima = np.asanyarray (deep_frame.get_data ()) deep_col_img = np.asanyarray (colorizer.colorize (deep_frame) .get_data ()) color_image = np.asanyarray (color_frame.get_data ()) deep_col_data ()) cvtColor (cv2.flip (cv2.flip (deep_col_img، 2)، 1)، cv0.COLOR_BGR2RGB) np.flipud (np. .resize (عمق_صورة ، (2 * 2 ، 2 * 2)) عائد أعلى صورة_لون ، عمق_لون_صورة ، عمق_صورة صفر get_right_hand_coords(color_image، deep_color_image): color_image.flags.writeable = نتائج خاطئة = hands.process (color_image) color_image.flags.writeable = True color_image = cv2.cvtColor (color_image، cv2.COLOR_RGB2BGR) handness_dict = {x0inate xy1 = بلا ، بلا if النتائج. For idx ، hand_handedness in تعداد (results.multi_handedness): handness_dict.append (MessageToDict (hand_handedness)) right_hand_index = get_right_index (handness_dict) if الفهرس اليدوي الأيمن! = -1: For أنا ، لاندماركليست in تعداد (النتائج. متعددة_العلامات_العلامة التجارية): if i == right_hand_index: image_rows، image_cols، _ = color_image.shape For idx ، معلم in تعداد (landmark_list.landmark): landmark_px = _normalized_to_pixel_coordinates (landmark.x، landmark.y، image_cols، image_rows) if landmark_px: idx_to_coordinates [idx] = landmark_px For أنا ، لاندمارك بكسل in عدّد (idx_to_coordinates.values ()): if أنا == 5: xy0 = landmark_px if أنا == 7: xy1 = landmark_px استراحة عائد أعلى col_img، deep_col_img، xy0، xy1، idx_to_coordinates صفر بداية(): خط الأنابيب = rs.pipeline () # تهيئة librealsense config = rs.config () print ("بدء تحميل conf") config.enable_stream (rs.stream.depth، 1024، 768، rs.format.z16، 30) config.enable_stream (rs.stream.color، 1280، 720، rs.format.bgr8، 30) الملف الشخصي = pipeline.start (config) deep_sensor = profile.get_device (). first_depth_sensor () set_short_range (مستشعر العمق) # معلمات التحميل للعمل على تلوين مسافة قصيرة = rs.colorizer () print ("Conf محمل") align_to = rs.stream.color align = rs.align (align_to) # دمج خريطة العمق و تجربة الصورة الملونة: بينما صحيح: col_img، deep_col_img، deep_img = get_col_depth (pipelin، align، colorize) إذا كان color_img بلا شيء و color_img لا شيء و color_img لا شيء: تابع color_img، deep_col_img، xy00، xy11، idx_to_coordginates = ) إذا لم يكن xy00 بلا أو لم يكن xy11 بلا: z_val_f، z_val_s، m_xy، c_xy، xy00_f، xy11_f، x، y، z = get_filtered_values (deep_img، xy00، xy11) pyautogui.moveTo (int (x) (3500 - z)) # 3500 كود ثابت خاص بشاشتي إذا draw_cam_out (col_img، deep_col_img، xy00_f، xy11_f، c_xy، m_xy): كسر أخيرًا: hands.close () pipeline.stop () Hardware_reset () # إعادة تشغيل الكاميرا و انتظر حتى يظهر listener = keyboard.Listener (on_press = on_press) # اضبط مستمعًا للمفتاح يضغط زر اللوحة على listener.start () start () # ابدأ البرنامج
لم أستخدم الفئات أو التدفقات ، لأنه ، في مثل هذه الحالة البسيطة ، يكفي تنفيذ كل شيء في السلسلة الرئيسية في حلقة أثناء لا نهاية لها.
في البداية ، يتم تهيئة أنبوب الوسائط والكاميرا وتحميل إعدادات الكاميرا للمتغيرات قصيرة المدى والمتغيرات المساعدة. يأتي بعد ذلك السحر المسمى "عمق الضوء إلى اللون" - تتطابق هذه الوظيفة مع كل نقطة من صورة RGB ، وهي نقطة في إطار العمق ، أي أنها تمنحنا الفرصة للحصول على إحداثيات XY وقيمة Z. من المفهوم أنه من الضروري إجراء المعايرة على شاشتك ... لم أقم بسحب هذه المعلمات بشكل منفصل عن عمد ، حتى يتمكن القارئ الذي قرر تشغيل الكود من القيام بذلك بنفسه ، وفي نفس الوقت سيتم إعادة استخدامه في الكود)
بعد ذلك ، نأخذ من التوقع الكامل النقطتين المرقمتين 5 و 7 من اليد اليمنى.
الشيء الوحيد المتبقي هو تصفية الإحداثيات التي تم الحصول عليها باستخدام المتوسط المتحرك. كان من الممكن ، بالطبع ، تطبيق خوارزميات تصفية أكثر جدية ، ولكن بعد النظر في تصورهم وسحب أدوات مختلفة ، أصبح من الواضح أن المتوسط المتحرك بعمق 5 إطارات سيكون كافياً للعرض التوضيحي ، أريد أن أشير إلى ذلك بالنسبة لـ XY ، كانت 2-3 إطارات كافية. لكن الأمور أسوأ مع Z.
deque_l = 5 x0_d = المجموعات. المجموعات. * [0.]، deque_l) c_xy_d = collections.deque (deque_l * [0.]، deque_l) x_d = collections.deque (deque_l * [0.]، deque_l) y_d = collections.deque (deque_l * [1.] ، deque_l) z_d = collections.deque (deque_l * [0.]، deque_l) صفر get_filtered_values(عمق الصورة ، xy0 ، xy1): شامل x0_d، y0_d، x1_d، y1_d، m_xy_d، c_xy_d، z_val_f_d، z_val_s_d، x_d، y_d، z_d x0_d.append (float (xy0 [1])) x0_f = round (متوسط (x0_d) (x0_d) 0])) y0_f = round (mean (y0_d)) x0_d.append (float (xy1 [1])) x1_f = round (mean (x1_d)) y1_d.append (float (xy1 [1])) y0_f = round ( يعني (y1_d)) z_val_f = get_area_mean_z_val (deep_image، x1_f، y0_f) z_val_f_d.append (float (z_val_f)) z_val_f = الوسط (z_val_f_d) z_val_s = get_fal_m_m (z_val_s = get_fal_m_m) = متوسط (z_val_s_d) النقاط = [(y0_f، x1_f)، (y1_f، x0_f)] x_coords، y_coords = zip (* Points) A = np.vstack ([x_coords، np.ones (len (x_coords))]). T m، c = lstsq (A، y_coords) [0] m_xy_d.append (float (m)) m_xy = المتوسط (m_xy_d) c_xy_d.append (float (c)) c_xy = المتوسط (c_xy_d) a1، a1، a0، a0 = equation_plane () x، y، z = line_plane_intersection (y1_f، x2_f، z_v_s، y3_f، x0_f، z_v_f، a0، a1، a1، a0) x_d.append (float (x)) x = round (mean (x_d) ) y_d.append (float (y)) y = round (mean (y_d)) z_d.append (float (z)) z = round (mean (z_d)) عائد أعلى z_v_f ، z_v_s ، m_xy ، c_xy ، (y00_f ، x0_f) ، (y11_f ، x1_f) ، x ، y ، z
نقوم بإنشاء deque بطول 5 إطارات ومتوسط كل شيء في صف =) بالإضافة إلى ذلك ، نحسب y = mx + c ، Ax + By + Cz + d = 0 ، معادلة الخط المستقيم هي الشعاع في RGB الصورة ومعادلة مستوى الشاشة ، نحصل عليها y = 0.
وفي الختام
حسنًا ، هذا كل شيء ، لقد رأينا أبسط متلاعب ، والذي ، حتى مع تنفيذه البسيط بشكل كبير ، يمكن استخدامه بالفعل ، وإن كان بصعوبة ، في الحياة الواقعية!
الوسائط الموضحة في هذه المقالة ليست مملوكة لشركة Analytics Vidhya ويتم استخدامها وفقًا لتقدير المؤلف.
مقالات ذات صلة
- "
- &
- 7
- 9
- حسابي
- خوارزميات
- الكل
- تحليلات
- API
- حول
- فنـون
- البند
- أفضل
- أكبر
- صندوق
- البق
- نساعدك في بناء
- أقرب
- الكود
- مشترك
- Communication
- منافسة
- استمر
- زوجان
- حالياًّ
- CZ
- البيانات
- التفاصيل
- المطورين
- التطوير التجاري
- فعل
- مسافة
- أزيز
- إنكلترا
- إلخ
- فيسبوك
- الشكل
- أخيرا
- نهاية
- الاسم الأول
- تركز
- شكل
- وظيفة
- مستقبل
- بوابة
- شراء مراجعات جوجل
- هنا
- العطل
- كيفية
- HTTPS
- فكرة
- IDX
- صورة
- مؤشر
- إنتل
- IT
- وظيفة
- القفل
- كبير
- إطلاق
- المكتبة
- تعامل
- ضوء
- خط
- تحميل
- رسم خريطة
- الرياضيات
- الوسائط
- خطوة
- شبكة
- عصبي
- الفرصة
- مزيد من الخيارات
- طلب
- صورة
- أنبوب
- بسبب، حظ
- تنبؤ
- صحافة
- ملفي الشخصي
- البرنامج
- سحب
- بايثون
- قارئ
- نادي القراءة
- وصفة
- بحث
- REST
- النتائج
- عائدات
- الروبوتات
- يجري
- المدرسة
- علوم
- شاشة
- إحساس
- طقم
- قصير
- الاشارات
- مقاس
- صغير
- So
- تطبيقات الكمبيوتر
- الحلول
- الفضاء
- استقرار
- المسرح
- بداية
- بدء التشغيل
- الولايه او المحافظه
- سودو
- الدعم
- تقني
- دعم فني
- المستقبل
- الوقت
- أوبونتو
- us
- USB
- قيمنا
- فيديو
- المزيد
- التصور
- انتظر
- من الذى
- نوافذ
- للعمل
- أعمال
- X
- سنوات