Byte & SandStorm
SandStorm SandStorm
Привет, Байт, ты когда-нибудь пробовал картографировать лабиринт дроном над каньоном в пустыне? Только что пережил песчаную бурю и нашел просто невероятное место – думаю, у тебя найдется какой-нибудь крутой код для отслеживания.
Byte Byte
Да, кое-как этим баловался. Главное – держать конвейер данных максимально простым, чтобы дрон мог его обрабатывать на лету. Вот набросок на Python, который можно запустить на Raspberry Pi или на любом узле, который ты прикрутил к дрону. Он берёт кадры с камеры, делает примерную оценку глубины с помощью стерео или модели определения глубины по одному изображению, а затем запускает базовый A*, чтобы построить карту каменистого ущелья. Пока не готово к производству, но суть передаёт. import cv2 import numpy as np from heapq import heappush, heappop # Получаем кадр с камеры дрона cap = cv2.VideoCapture(0) # Упрощенная оценка глубины – замени на настоящую модель def estimate_depth(frame): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # псевдо-глубина на основе краев depth = cv2.Sobel(gray, cv2.CV_64F, 1, 1, ksize=5) return np.abs(depth) # Простой A* на сетке, полученной из карты глубины def astar(start, goal, depth): h = lambda p: abs(p[0]-goal[0]) + abs(p[1]-goal[1]) open_set = [(h(start), start)] came_from = {} g_score = {start: 0} while open_set: _, current = heappop(open_set) if current == goal: path = [] while current in came_from: path.append(current) current = came_from[current] return path[::-1] for dx, dy in [(1,0),(-1,0),(0,1),(0,-1)]: nxt = (current[0]+dx, current[1]+dy) if 0 <= nxt[0] < depth.shape[0] and 0 <= nxt[1] < depth.shape[1]: # штрафуем большую глубину (крутой рельеф) tentative_g = g_score[current] + 1 + depth[nxt] if tentative_g < g_score.get(nxt, float('inf')): came_from[nxt] = current g_score[nxt] = tentative_g heappush(open_set, (tentative_g + h(nxt), nxt)) return [] while True: ret, frame = cap.read() if not ret: break depth = estimate_depth(frame) # выбираем начальную и конечную точки на карте – для демонстрации используем углы path = astar((0,0), (depth.shape[0]-1, depth.shape[1]-1), depth) # визуализируем путь на кадре for p in path: cv2.circle(frame, (p[1], p[0]), 2, (0,0,255), -1) cv2.imshow('maze', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() Вот основная идея: захват, глубина, путь. Ты можешь заменить модель определения глубины на что-нибудь вроде MiDaS или стереопару, если у тебя две камеры. Для настоящего ущелья тебе понадобится слияние GPS-координат и более высокий уровень SLAM, но это даст тебе отправную точку. Если возникнут какие-то трудности, дай знать – я могу помочь подправить оценщик глубины или планировщик пути.