@ -5,10 +5,11 @@ import sys
import time
import time
from pathlib import Path
from pathlib import Path
import argparse
import argparse
import pandas as pd
sys . path . append ( str ( Path ( __file__ ) . parent . parent ) )
sys . path . append ( str ( Path ( __file__ ) . parent . parent ) )
from skeleton . mediapipe_detector import MediaPipeDetector
from skeleton . mediapipe_detector import MediaPipeDetector
from ml_gestures . dynamic. feature_extractor import extract_sequence
from ml_gestures _ dynamic. feature_extractor import extract_sequence
def main ( ) :
def main ( ) :
parser = argparse . ArgumentParser ( )
parser = argparse . ArgumentParser ( )
@ -18,6 +19,15 @@ def main():
parser . add_argument ( ' --duration ' , type = float , default = 3.0 , help = ' Длительность записи (сек) ' )
parser . add_argument ( ' --duration ' , type = float , default = 3.0 , help = ' Длительность записи (сек) ' )
args = parser . parse_args ( )
args = parser . parse_args ( )
output_path = Path ( args . output )
# Создаём файл с заголовком, если е г о ещё нет
if not output_path . exists ( ) :
with open ( output_path , ' w ' , newline = ' ' ) as f :
writer = csv . writer ( f )
header = [ ' label ' , ' sequence_id ' , ' frame_idx ' ] + [ f ' f { i } ' for i in range ( 99 ) ]
writer . writerow ( header )
detector = MediaPipeDetector ( )
detector = MediaPipeDetector ( )
cap = cv2 . VideoCapture ( args . camera )
cap = cv2 . VideoCapture ( args . camera )
if not cap . isOpened ( ) :
if not cap . isOpened ( ) :
@ -26,8 +36,7 @@ def main():
# Определяем следующий ID последовательности
# Определяем следующий ID последовательности
try :
try :
import pandas as pd
df = pd . read_csv ( output_path )
df = pd . read_csv ( args . output )
next_id = df [ ' sequence_id ' ] . max ( ) + 1 if not df . empty else 0
next_id = df [ ' sequence_id ' ] . max ( ) + 1 if not df . empty else 0
except :
except :
next_id = 0
next_id = 0
@ -46,14 +55,22 @@ def main():
if result [ ' success ' ] :
if result [ ' success ' ] :
landmarks = result [ ' landmarks ' ]
landmarks = result [ ' landmarks ' ]
vis = detector . draw_landmarks ( frame , result [ ' pose_landmarks ' ] )
vis = detector . draw_landmarks ( frame , result [ ' pose_landmarks ' ] )
else :
vis = frame
landmarks = None
# Если мы в режиме записи
if recording :
if recording :
if landmarks is not None :
sequence . append ( landmarks )
sequence . append ( landmarks )
elapsed = time . time ( ) - start_time
elapsed = time . time ( ) - start_time
# Отображаем прогресс записи
cv2 . putText ( vis , f " RECORDING... { elapsed : .1f } / { args . duration } " , ( 10 , 30 ) ,
cv2 . FONT_HERSHEY_SIMPLEX , 0.7 , ( 0 , 0 , 255 ) , 2 )
if elapsed > = args . duration :
if elapsed > = args . duration :
recording = False
recording = False
# Сохраняем последовательность
seq_features = extract_sequence ( sequence )
seq_features = extract_sequence ( sequence )
with open ( args. output, ' a ' , newline = ' ' ) as f :
with open ( output_path , ' a ' , newline = ' ' ) as f :
writer = csv . writer ( f )
writer = csv . writer ( f )
for i , feat in enumerate ( seq_features ) :
for i , feat in enumerate ( seq_features ) :
writer . writerow ( [ args . label , next_id , i ] + feat . tolist ( ) )
writer . writerow ( [ args . label , next_id , i ] + feat . tolist ( ) )
@ -61,12 +78,7 @@ def main():
sequence = [ ]
sequence = [ ]
next_id + = 1
next_id + = 1
else :
else :
vis = frame
# Ожидание нажатия пробела
if recording :
cv2 . putText ( vis , f " RECORDING... { elapsed : .1f } / { args . duration } " , ( 10 , 30 ) ,
cv2 . FONT_HERSHEY_SIMPLEX , 0.7 , ( 0 , 0 , 255 ) , 2 )
else :
cv2 . putText ( vis , f " Press SPACE to record ' { args . label } ' " , ( 10 , 30 ) ,
cv2 . putText ( vis , f " Press SPACE to record ' { args . label } ' " , ( 10 , 30 ) ,
cv2 . FONT_HERSHEY_SIMPLEX , 0.7 , ( 0 , 255 , 0 ) , 2 )
cv2 . FONT_HERSHEY_SIMPLEX , 0.7 , ( 0 , 255 , 0 ) , 2 )
@ -75,6 +87,36 @@ def main():
if key == ord ( ' q ' ) :
if key == ord ( ' q ' ) :
break
break
if key == ord ( ' ' ) and not recording :
if key == ord ( ' ' ) and not recording :
# Обратный отсчёт на живом видео
for i in range ( 3 , 0 , - 1 ) :
# Получаем свежий кадр для отсчёта
ret , frame = cap . read ( )
if not ret :
break
frame = cv2 . flip ( frame , 1 )
result = detector . detect ( frame )
if result [ ' success ' ] :
vis = detector . draw_landmarks ( frame , result [ ' pose_landmarks ' ] )
else :
vis = frame
cv2 . putText ( vis , f " Starting in { i } ... " , ( frame . shape [ 1 ] / / 2 - 100 , frame . shape [ 0 ] / / 2 ) ,
cv2 . FONT_HERSHEY_SIMPLEX , 1.5 , ( 0 , 0 , 255 ) , 3 )
cv2 . imshow ( ' Record dynamic gesture ' , vis )
cv2 . waitKey ( 1000 )
# Показываем "GO!"
ret , frame = cap . read ( )
if ret :
frame = cv2 . flip ( frame , 1 )
result = detector . detect ( frame )
if result [ ' success ' ] :
vis = detector . draw_landmarks ( frame , result [ ' pose_landmarks ' ] )
else :
vis = frame
cv2 . putText ( vis , " GO! " , ( frame . shape [ 1 ] / / 2 - 50 , frame . shape [ 0 ] / / 2 ) ,
cv2 . FONT_HERSHEY_SIMPLEX , 2 , ( 0 , 255 , 0 ) , 3 )
cv2 . imshow ( ' Record dynamic gesture ' , vis )
cv2 . waitKey ( 500 )
# Начинаем запись
recording = True
recording = True
start_time = time . time ( )
start_time = time . time ( )
sequence = [ ]
sequence = [ ]