Zephyrnet Logosu

30 dakikada LiDAR'a dayalı El Poz Tahmini

Tarih:

Bu makale, Veri Bilimi Blogathon

Giriş

Herkese merhaba! Cyberpunk henüz hayatımıza bu kadar girmemiş ve nöro arayüzler ideal olmaktan uzak olsa da, LiDAR manipülatörlerin geleceğine giden yolda ilk aşama olabilir. Bu nedenle, tatillerde sıkılmamak için, bir bilgisayarın ve muhtemelen bir ekskavatöre, uzay gemisine, drone'a veya sobaya kadar herhangi bir cihazın kontrolleri hakkında biraz hayal kurmaya karar verdim.

Ana fikir, fareyi hareket ettirmek, tüm eli değil, sadece işaret parmağını hareket ettirmek, bu da ellerinizi klavyeden çekmeden menüde gezinmenizi, düğmelere basmanızı ve kısayol tuşlarıyla birlikte bir gerçek klavye ninjası! Kaydırma veya kaydırma hareketleri eklerseniz ne olur? Bence bomba olacak! Ama bu ana kadar hala birkaç yıl beklememiz gerekiyor)

Geleceğin manipülatörünün prototipini oluşturmaya başlayalım

Neye ihtiyacın var:

  1. LiDAR Intel Realsense L515 ile kamera.

  2. Python'da programlama yeteneği

  3. Sadece biraz okul matematiğini hatırla

  4. Monitörde kamera için montaj aka tripod

Fotoğraf makinesini aliexpress ile bir tripoda bağladık, çok kullanışlı, hafif ve ucuz olduğu ortaya çıktı)

resim | El Poz Tahmini LiDAR

KAYNAK

resim 2 | El Poz Tahmini LiDAR

KAYNAK

Prototipin nasıl ve neye göre yapılacağını anlıyoruz

Bu görevi gerçekleştirmek için birçok yaklaşım vardır. Dedektörü veya el segmentasyonunu kendiniz eğitebilir, sağ elin ortaya çıkan görüntüsünü kesebilir ve ardından Facebook araştırmasından bu harika depoyu görüntüye uygulayabilir, mükemmel bir sonuç alabilir veya daha da kolaylaştırabilirsiniz.

Bu bağlantıyı okuduktan sonra medya kanalı deposunu kullanmak için, Bunun bugün için en iyi seçeneklerden biri olduğunu anlayabilirsiniz.

İlk olarak, her şey kutudan çıktığı gibi zaten mevcut – tüm ön koşullar dikkate alındığında kurulum ve başlatma 30 dakika sürecektir.

İkincisi, güçlü bir geliştirme ekibi sayesinde, yalnızca El Poz Tahmininde Son Teknolojiyi almakla kalmaz, aynı zamanda anlaşılması kolay bir API sağlarlar.

Üçüncüsü, ağ CPU üzerinde çalışmaya hazırdır, bu nedenle giriş eşiği minimumdur.

Muhtemelen neden buraya gelmediğimi ve bu yarışmanın kazananlarının depolarını kullanmadığımı soracaksınız. Aslında, çözümlerini biraz ayrıntılı olarak inceledim, oldukça prod-hazır, milyonlarca ızgara yığını vs. yok. Ama bana göre en büyük sorun, derinlik görüntüleri ile çalışmaları. Bunlar akademisyen olduğu için tüm verileri Matlab üzerinden dönüştürmekten çekinmediler ayrıca derinliklerin çekildiği çözünürlük de bana küçük geldi. Bunun sonuç üzerinde derin bir etkisi olabilir. Bu nedenle, RGB resmindeki kilit noktaları elde etmek ve Derinlik Çerçevesinde Z ekseni boyunca değeri XY koordinatlarıyla almak en kolay yol gibi görünüyor. Şimdi görev, bir şeyi çok fazla optimize etmek değil, bu yüzden geliştirme açısından daha hızlı olduğu için yapacağız.

Okul matematiğini hatırlamak

Daha önce yazdığım gibi, fare imlecinin olması gereken noktanın koordinatını elde etmek için, parmağın falanksının iki kilit noktasından geçen bir çizgi oluşturmamız ve çizgi ile çizginin kesişme noktasını bulmamız gerekiyor. monitörün düzlemi.

görüntü uçak | El Poz Tahmini LiDAR

KAYNAK

Resim, monitörün düzlemini ve onu kesen çizgiyi şematik olarak göstermektedir. Matematiğe buradan bakabilirsiniz.

İki nokta kullanarak, uzayda düz bir çizginin parametrik bir temsilini elde ederiz.

parametrik gösterim | El Poz Tahmini LiDAR
değişkenler

Okul matematik müfredatına çok fazla odaklanmayacağım.

Bir kamerayla çalışmak için bir kitaplık kurma

Bu belki de bu işin en zor kısmı. Görünüşe göre, Ubuntu için kamera yazılımı çok kaba, liberal anlamda her türlü böcek, aksaklık ve bir tef ile dans ediyor.

Şimdiye kadar kameranın garip davranışını yenemedim, bazen başlangıçta parametreleri yüklemiyor.

Kamera, bilgisayarı yeniden başlattıktan sonra yalnızca bir kez çalışır !!! Ancak bir çözüm var: Her başlatmadan önce, kameranın yazılımsal donanım sıfırlamasını yapın, USB'yi sıfırlayın ve belki her şey yoluna girecek. Bu arada, Windows 10 için orada her şey yolunda. Geliştiricilerin Windows'a dayalı robotları hayal etmesi garip =)

Ubuntu 20 altında gerçek anlamda bir anlam ifade etmek için şunu yapın:

$ sudo apt-get install libusb-1.0-0-dev Sonra cmake'i yeniden çalıştırın ve kurulum yap. Burada is işe yarayan eksiksiz bir tarif için ben: $ sudo apt-get install libusb-1.0-0-dev $ git klonu https://github.com/IntelRealSense/librealsense.git $ cd librealsense/ $ mkdir build && cd build

Çeşitlerden toplandıktan sonra, az çok kararlı olacaktır. Teknik destekle bir aylık iletişim, Ubuntu 16'yı kurmanız veya acı çekmeniz gerektiğini ortaya çıkardı. Bunu kendin seçtim, biliyor musun?

Sinir ağının inceliklerini anlamaya devam ediyoruz

Şimdi parmak ve fare işleminin başka bir videosunu görelim. Lütfen işaretçinin tek bir yerde duramayacağını ve olduğu gibi amaçlanan noktanın etrafında yüzdüğünü unutmayın. Aynı zamanda, ihtiyacım olan kelimeye kolayca yönlendirebilirim, ancak bir harfle daha zor, imleci dikkatlice hareket ettirmem gerekiyor:

Bu, anladığınız gibi, elimi sıkmak değil, tatillerde sadece bir bardak New England DIPA içtim =) Her şey, lidardan elde edilen değerlere dayalı olarak kilit noktaların ve Z-koordinatlarının sürekli dalgalanmalarıyla ilgili.

Hadi daha yakından bakalım:

Medya kanalından SOTA'mızda kesinlikle daha az dalgalanma var, ancak bunlar da var. Görünüşe göre, mevcut çerçeve ve tren ağındaki geçmiş çerçeve ısı haritasından prokid vaniya kullanarak bununla mücadele ediyorlar – daha fazla stabilite sağlıyor, ancak %100 değil.

Ayrıca, bana öyle geliyor ki, işaretlemenin özgüllüğü bir rol oynuyor. Çerçevenin çözünürlüğünün her yerde farklı olduğu ve çok büyük olmadığı gerçeğinden bahsetmiyorum bile, bu kadar çok sayıda çerçeve üzerinde aynı işaretlemeyi yapmak pek mümkün değildir. Ayrıca, farklı çalışma süreleri ve kameranın pozlama miktarı nedeniyle büyük olasılıkla sabit olmayan ışık titremesini görmüyoruz. Ve ağ ayrıca ısı haritasından ekrandaki anahtar noktaların sayısına eşit bir sandviç döndürür, bu tensörün boyutu BxNx96x96'dır, burada N anahtar noktaların sayısıdır ve tabii ki eşikten sonra ve orijinale yeniden boyutlandırılır çerçeve boyutu, aldığımızı alırız (

Isı haritası oluşturma örneği:

el poz tahmini | El Poz Tahmini LiDAR

KAYNAK

Kod incelemesi

Tüm kodlar bu depodadır ve çok kısadır. Ana dosyaya bir göz atalım ve gerisini kendiniz görelim.

ithalat cv2
ithalat medya borusu as mp
ithalat dizi as np
ithalat Pyautogui
ithalat pyrealsense2.pyrealsense2 as rs
itibaren google.protobuf.json_format ithalat MesajaDict
itibaren mediapipe.python.solutions.drawing_utils ithalat _normalized_to_pixel_koordinatları
itibaren giriş ithalat tuş takımı
itibaren utils.ortak ithalat get_filtered_values, Draw_cam_out, get_right_index
itibaren utils.hard_reset ithalat donanım_sıfırlama
itibaren utils.set_options ithalat set_short_range pyautogui.FAILSAFE = Yanlış mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands # El Pozu Tahmini eller = mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.9) def on_press(anahtar):
if anahtar == klavye.Key.ctrl: pyautogui.leftClick()
if anahtar == klavye.Key.alt: pyautogui.rightClick()
def renk_derinliği al(boru hattı, hizalama, renklendirici): çerçeveler = boru hattı.wait_for_frames(timeout_ms=15000) # kameradan bir çerçeve bekleniyoralign_frames = align.process(frames) deep_frame =align_frames.get_depth_frame() color_frame =align_frames.get_color_frame()
if değil derinlik_çerçevesi or değil renk_çerçevesi:
dönüş Yok, Yok, Yok deep_ima = np.asanyarray(depth_frame.get_data()) deep_col_img = np.asanyarray(colorizer.colorize(depth_frame).get_data()) color_image = np.asanyarray(color_frame.get_data())depth_col_img = cv2. cvtColor(cv2.flip(cv2.flip(depth_col_img, 1), 0), cv2.COLOR_BGR2RGB) color_img = cv2.cvtColor(cv2.flip(cv2.flip(color_img, 1), 0), cv2.COLOR_BG_img =GB) np.flipud(np.fliplr(depth_img)) deep_col_img = cv2.resize(depth_col_img, (2 * 1280, 2 * 720)) col_img = cv2.resize(col_img, (2 * 1280, 2 * 720))depth_img = cv2 .resize(depth_img, (2 * 1280, 2 * 720))
dönüş renk_görsel, derinlik_renk_görüntü, derinlik_görüntü
def get_right_hand_coords(color_image,depth_color_image): color_image.flags.writeable = Yanlış sonuçlar = hands.process(color_image) color_image.flags.writeable = True color_image = cv2.cvtColor(color_image, cv2.COLOR_RGB2BGR) handedness_dict = [] idx_to_coordinates = {} xy0 = Yok, Yok
if sonuçlar.multi_hand_landmarks:
için idx, el becerisi in numaralandırma(results.multi_handedness): handedness_dict.append(MessageToDict(hand_handedness)) right_hand_index = get_right_index(handedness_dict)
if sağ_el_index != -1:
için ben, dönüm noktası_listesi in numaralandır(results.multi_hand_landmarks):
if i == right_hand_index: image_rows, image_cols, _ = color_image.shape
için idx, yer işareti in enumerate(landmark_list.landmark): dönüm noktası_px = _normalized_to_pixel_coordinates(landmark.x, simgesel yapı.y, image_cols, image_rows)
if simgesel yapı_px: idx_to_koordinatlar[idx] = simgesel yapı_px
için ben, dönüm noktası_px in numaralandır(idx_to_coordinates.values()):
if i == 5: xy0 = dönüm noktası_px
if i == 7: xy1 = dönüm noktası_px
kırılma
dönüş col_img, deep_col_img, xy0, xy1, idx_to_koordinatları
def başlama(): boru hattı = rs.pipeline() # initialize librealsense config = rs.config() print("Start load 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) profil = boru hattı.start(config) deep_sensor = profile.get_device (). first_depth_sensor () set_short_range (depth_sensor) # kısa mesafede çalışmak için parametreleri yükleyin colorizer = rs.colorizer () print ("Conf yüklendi") align_to = rs.stream.color align = rs.align (align_to) # derinlik haritasını birleştir ve renkli görüntü deneyin: while True: col_img, deep_col_img, deep_img = get_col_depth (boru hattı, hizalama, renklendirme) eğer color_img Yok ve color_img Yok ise ve color_img Yok ise: devam color_img, deep_col_img, xy00, xy11, idx_to_coordinates_coordinates, get_right ( ) xy00 Yok değilse veya xy11 Yok değilse: z_val_f, z_val_s, m_xy, c_xy, xy00_f, xy11_f, x, y, z = get_filtered_values ​​​​(depth_img, xy00, xy11) pyautogui.moveTot (int (x), int (3500 - z)) # Draw_cam_out (col_img, deep_col_img, xy3500_f, xy00_f, c_xy, m_xy) ise monitörüme özel 11 sabit kod: break nihayet: hands.close () boru hattı.stop () Hardware_reset () # kamerayı yeniden başlatın ve görünmesini bekleyin listener = klavye.Listener (on_press = on_press) # key için bir dinleyici ayarla pano düğmesi listener'a basar.start () start () # programı başlat

Sınıfları veya akışları kullanmadım, çünkü bu kadar basit bir durum için ana iş parçacığındaki her şeyi sonsuz bir while döngüsünde yürütmek yeterli.

En başta medya borusu, kamera başlatılır, kısa mesafe ve yardımcı değişkenler için kamera ayarları yüklenir. Ardından, “derinliği aydınlatan renge” adı verilen sihir gelir - bu işlev, RGB görüntüsündeki her noktayı, Derinlik Çerçevesindeki bir noktayı eşleştirir, yani bize XY koordinatlarını, Z değerini alma fırsatı verir. Monitörünüzde kalibrasyon yapmanız gerektiği anlaşıldı… Kodu çalıştırmaya karar veren okuyucu kendisi yapsın diye bu parametreleri kasten ayrı ayrı çıkarmadım, aynı zamanda kodda tekrar kullanılacak)

Daha sonra, tüm tahminden sadece sağ elin 5 ve 7 numaralı noktalarını alıyoruz.

el noktaları

Yapılması gereken tek şey, elde edilen koordinatları hareketli bir ortalama kullanarak filtrelemek. Daha ciddi filtreleme algoritmaları uygulamak elbette mümkündü ama görselleştirmelerine bakıp çeşitli kaldıraçları çektikten sonra, demo için 5 karelik bir hareketli ortalamanın yeterli olacağı anlaşıldı, belirtmek isterim ki XY için 2-3 kare yeterliydi. ama işler Z ile daha kötü.

deque_l = 5 x0_d = collections.deque(deque_l * [0.], deque_l) y0_d = collections.deque(deque_l * [0.], deque_l) x1_d = collections.deque(deque_l * [0.], deque_l) y1_d = collections.deque(deque_l * [0.], deque_l) z_val_f_d = collections.deque(deque_l * [0.], deque_l) z_val_s_d = collections.deque(deque_l * [0.], deque_l) m_xy_d = collections.deque(deque_l) * [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 * [0.] , deque_l) z_d = collections.deque(deque_l * [0.], deque_l)
def get_filtered_values(derinlik_görüntüsü, xy0, xy1):
global 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_y = yuvarlak(ortalama(x0_d.)) 0])) y0_f = yuvarlak(ortalama(y0_d)) x0_d.append(kayan(xy0[1])) x1_f = yuvarlak(orta(x1_d)) y1_d.append(kayan(xy1[1])) y1_f = yuvarlak( ortalama(y0_d)) z_val_f = get_area_mean_z_val(depth_image, x1_f, y1_f) z_val_f_d.append(float(z_val_f)) z_val_f = ortalama(z_val_f_d) z_val_s = get_val_z_d(pend_mean_z_) = ortalama(z_val_s_d) puan = [(y0_f, x0_f), (y1_f, x1_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(kayan(m)) m_xy = ortalama(m_xy_d) c_xy_d.append(kayan(c)) c_xy = ortalama(c_xy_d) a0, a1, a1, a0 = denklem_düzlem() x, y, z = çizgi_düzlem_intersection(y0_f, x1_f, z_v_s, y2_f, x3_f, z_v_f, a0, a0, a1, a1) x_d.append(kayan(x)) x = yuvarlak(ortalama(x_d) ) y_d.append(kayan(y)) y = yuvarlak(orta(y_d)) z_d.append(kayan(z)) z = yuvarlak(orta(z_d))
dönüş z_v_f, z_v_s, m_xy, c_xy, (y00_f, x0_f), (y11_f, x1_f), x, y, z

5 kare uzunluğunda bir deque oluşturuyoruz ve bir satırdaki her şeyin ortalamasını alıyoruz =) Ek olarak, y = mx + c, Ax + By + Cz + d = 0 hesaplıyoruz, düz çizginin denklemi RGB'deki ışındır resim ve monitör düzleminin denklemini, y = 0 elde ederiz.

Sonuç

Pekala, hepsi bu kadar, çarpıcı biçimde basit yürütmesiyle bile, gerçek hayatta zorlukla da olsa halihazırda kullanılabilen en basit manipülatörü gördük!

Bu makalede gösterilen medya Analytics Vidhya'ya ait değildir ve Yazarın takdirine bağlı olarak kullanılır.

Plato Ai. Web3 Yeniden Düşünüldü. Güçlendirilmiş Veri Zekası.
Erişmek için buraya tıklayın.

Kaynak: https://www.analyticsvidhya.com/blog/2021/08/hand-pose-estimation-based-on-lidar-in-30-minutes/

spot_img

En Son İstihbarat

spot_img