Initial commit

This commit is contained in:
moscovskayaliza
2026-03-20 17:01:27 +03:00
commit 14fb06a903
19 changed files with 1071 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
import cv2
import os
import csv
import sys
from pathlib import Path
import argparse
sys.path.append(str(Path(__file__).parent.parent))
from skeleton.mediapipe_detector import MediaPipeDetector
from ml_gestures.feature_extractor import normalize_landmarks
def main():
parser = argparse.ArgumentParser(description='Разметка изображений для обучения')
parser.add_argument('--folder', required=True, help='Папка с изображениями')
parser.add_argument('--classes', default='dome,cross,none',
help='Список классов через запятую')
parser.add_argument('--output', default='gesture_data.csv',
help='Имя выходного CSV-файла')
args = parser.parse_args()
classes = [c.strip() for c in args.classes.split(',')]
key_to_class = {str(i+1): cls for i, cls in enumerate(classes)}
print("Классы:", classes)
detector = MediaPipeDetector()
image_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
image_files = [f for f in os.listdir(args.folder) if f.lower().endswith(image_extensions)]
image_files.sort()
print(f"Найдено {len(image_files)} изображений.")
csv_file = args.output
file_exists = os.path.isfile(csv_file)
if not file_exists:
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
# 99 признаков (33 точки * 3 координаты)
writer.writerow(['class'] + [f'f{i}' for i in range(99)])
for idx, filename in enumerate(image_files):
filepath = os.path.join(args.folder, filename)
print(f"\n[{idx+1}/{len(image_files)}] {filename}")
image = cv2.imread(filepath)
if image is None:
continue
result = detector.detect(image)
if not result['success']:
cv2.imshow('No skeleton', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
continue
landmarks = result['landmarks']
features = normalize_landmarks(landmarks) # вектор из 99 чисел
display = detector.draw_landmarks(image, result['pose_landmarks'])
h, w = display.shape[:2]
# Панель с инструкцией
overlay = display.copy()
cv2.rectangle(overlay, (0, h-80), (w, h), (50,50,50), -1)
cv2.addWeighted(overlay, 0.6, display, 0.4, 0, display)
y = h - 60
for i, cls in enumerate(classes):
cv2.putText(display, f"{i+1}:{cls}", (10 + i*120, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)
cv2.putText(display, "n:skip q:quit", (10, y+30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,0), 2)
cv2.imshow('Annotation', display)
key = cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
if key == ord('q'):
break
elif key == ord('n'):
continue
else:
key_char = chr(key) if key < 256 else None
if key_char in key_to_class:
selected = key_to_class[key_char]
with open(csv_file, 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([selected] + features.tolist())
print(f"Сохранено: {selected}")
else:
print("Неверная клавиша")
print("Готово.")
if __name__ == '__main__':
main()
+9
View File
@@ -0,0 +1,9 @@
class DummyRobot:
def set_speeds(self, linear, angular):
print(f"Robot: linear={linear:.2f}, angular={angular:.2f}")
def step(self):
pass
def quit(self):
pass
+137
View File
@@ -0,0 +1,137 @@
import pygame
import sys
import math
class MapSimulator:
def __init__(self, config):
pygame.init()
self.width = config.MAP_WIDTH
self.height = config.MAP_HEIGHT
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption("Robot Map Simulator")
self.clock = pygame.time.Clock()
self.font = pygame.font.SysFont(None, 24)
self.obstacles = config.MAP_OBSTACLES
self.start = config.START_POS
self.finish = config.FINISH_POS
self.robot_radius = config.ROBOT_RADIUS
if config.ROBOT_IMAGE_PATH:
try:
self.robot_image = pygame.image.load(config.ROBOT_IMAGE_PATH)
self.robot_image = pygame.transform.scale(self.robot_image,
(self.robot_radius*2, self.robot_radius*2))
except:
self.robot_image = None
else:
self.robot_image = None
self.reset()
def reset(self):
self.x, self.y = self.start
self.angle = 0.0
self.linear_speed = 0.0
self.angular_speed = 0.0
self.game_over = False
self.won = False
def set_speeds(self, linear, angular):
self.linear_speed = linear
self.angular_speed = angular
def update(self):
if self.game_over or self.won:
return
dt = 1/30.0
self.angle += self.angular_speed * dt * 2
dx = self.linear_speed * math.cos(self.angle) * dt * 100
dy = self.linear_speed * math.sin(self.angle) * dt * 100
new_x = self.x + dx
new_y = self.y + dy
# Ограничение границами карты
new_x = max(self.robot_radius, min(self.width - self.robot_radius, new_x))
new_y = max(self.robot_radius, min(self.height - self.robot_radius, new_y))
# Проверка столкновений с препятствиями
if not self.check_collision(new_x, new_y):
self.x, self.y = new_x, new_y
else:
self.game_over = True
# Проверка финиша
dist = math.hypot(self.x - self.finish[0], self.y - self.finish[1])
if dist < self.robot_radius:
self.won = True
def check_collision(self, x, y):
for ox, oy, ow, oh in self.obstacles:
closest_x = max(ox, min(x, ox + ow))
closest_y = max(oy, min(y, oy + oh))
dist = math.hypot(x - closest_x, y - closest_y)
if dist < self.robot_radius:
return True
return False
def draw(self):
self.screen.fill((255,255,255))
for obs in self.obstacles:
pygame.draw.rect(self.screen, (100,100,100), obs)
pygame.draw.circle(self.screen, (0,255,0),
(int(self.finish[0]), int(self.finish[1])), self.robot_radius, 2)
if self.robot_image:
rotated = pygame.transform.rotate(self.robot_image, -math.degrees(self.angle))
rect = rotated.get_rect(center=(int(self.x), int(self.y)))
self.screen.blit(rotated, rect)
else:
nose = (self.x + self.robot_radius * math.cos(self.angle),
self.y + self.robot_radius * math.sin(self.angle))
left = (self.x + self.robot_radius * math.cos(self.angle + 2.5),
self.y + self.robot_radius * math.sin(self.angle + 2.5))
right = (self.x + self.robot_radius * math.cos(self.angle - 2.5),
self.y + self.robot_radius * math.sin(self.angle - 2.5))
pygame.draw.polygon(self.screen, (0,0,255), [nose, left, right])
texts = [
f"Linear: {self.linear_speed:.2f}",
f"Angular: {self.angular_speed:.2f}",
]
y = 10
for t in texts:
surf = self.font.render(t, True, (0,0,0))
self.screen.blit(surf, (10, y))
y += 25
if self.game_over:
msg = self.font.render("GAME OVER Press R to restart", True, (255,0,0))
self.screen.blit(msg, (self.width//2 - 150, self.height//2))
elif self.won:
msg = self.font.render("YOU WIN! Press R to restart", True, (0,100,0))
self.screen.blit(msg, (self.width//2 - 120, self.height//2))
pygame.display.flip()
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
self.reset()
return True
def step(self):
if not self.handle_events():
return False
self.update()
self.draw()
self.clock.tick(30)
return True
def quit(self):
pygame.quit()