Разочарованное зависание видеопотокаPython

Программы на Python
Anonymous
Разочарованное зависание видеопотока

Сообщение Anonymous »

Я создаю счетчик отжиманий, который будет вслух подсчитывать количество повторений после обнаружения повторения. Я пытаюсь добавить pyttsx3 к моему текущему коду, чтобы он подсчитывал количество повторений. Код без pyttsx3 работает нормально, однако, когда я добавляю модуль pyttsx3, видеопоток имеет тенденцию зависать, когда код обнаруживает повтор. Мало того, он также неожиданно прекращался с длинной цепочкой сообщений об ошибках:
[DEBUG ] .Release() -> 1
[DEBUG ] .AddRef() -> 2
[DEBUG ] unimplemented method _ISpeechVoiceEvents_Phoneme called
[DEBUG ] .Release() -> 1
[DEBUG ] .AddRef() -> 2
[DEBUG ] unimplemented method _ISpeechVoiceEvents_Viseme called
[DEBUG ] .Release() -> 1
[DEBUG ] .AddRef() -> 2
[DEBUG ] .Release() -> 1

Process finished with exit code -1

Для справки: это часть моего кода без pyttsx3:
def load_video(self, dt):
ret, frame = self.capture.read()
if ret:
# Run pose estimation
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = self.pose.process(image_rgb)

# Extract relevant landmarks for push-up detection
if results.pose_landmarks is not None:
landmarks = results.pose_landmarks.landmark
left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
left_elbow = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value]
right_elbow = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value]
left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value]
right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value]
left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
left_knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]
right_knee = landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]

# Calculate angles for push-up detection
angle_left = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_elbow.x, left_elbow.y],
[left_wrist.x, left_wrist.y])
angle_right = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_elbow.x, right_elbow.y],
[right_wrist.x, right_wrist.y])
angle2 = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_hip.x, left_hip.y],
[left_knee.x, left_knee.y])
angle3 = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_hip.x, right_hip.y],
[right_knee.x, right_knee.y])

# Update stage based on angle criteria
if angle_left < 90 and angle_right < 90 and angle2 > 165 and angle3 > 165:
self.stage = "down"
else:
self.stage = "up"

# Increment counter if criteria met
if self.stage == "up" and self.prev_stage == "down":
self.counter += 1

self.prev_stage = self.stage

Вот код, который я пытался придумать:
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDRaisedButton
from kivy.graphics.texture import Texture
from kivy.uix.image import Image
from kivy.clock import Clock
import cv2
import mediapipe as mp
import numpy as np
import pyttsx3

mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

class App(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.engine = pyttsx3.init()

def load_video(self, dt):
ret, frame = self.capture.read()
if ret:
# Run pose estimation
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = self.pose.process(image_rgb)

# Extract relevant landmarks for push-up detection
if results.pose_landmarks is not None:
landmarks = results.pose_landmarks.landmark
left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
left_elbow = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value]
right_elbow = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value]
left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value]
right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value]
left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
left_knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]
right_knee = landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]

# Calculate angles for push-up detection
angle_left = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_elbow.x, left_elbow.y], [left_wrist.x, left_wrist.y])
angle_right = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_elbow.x, right_elbow.y], [right_wrist.x, right_wrist.y])
angle2 = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_hip.x, left_hip.y], [left_knee.x, left_knee.y])
angle3 = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_hip.x, right_hip.y], [right_knee.x, right_knee.y])

# Update stage based on angle criteria
if angle_left < 90 and angle_right < 90 and angle2 > 165 and angle3 > 165:
self.stage = "down"
else:
self.stage = "up"

# Increment counter if criteria met
if self.stage == "up" and self.prev_stage == "down":
self.counter += 1
# Speak the current count
self.engine.say(f"Rep number {self.counter}")
self.engine.runAndWait()

self.prev_stage = self.stage

def on_stop(self):
# Release pyttsx3 engine
self.engine.stop()
# Release OpenCV video capture and Mediapipe pose
self.capture.release()
self.pose.close()
super().on_stop()

if __name__ == '__main__':
App().run()

После того, как я столкнулся с ошибками, я удалил self.engine = pyttsx3.init(), self.engine.stop(), все равно не работало.
Я также пытался создать совершенно другую функцию, но безрезультатно:
def speak_count_async(self, count):
def speak():
self.engine.say(f"Rep number {count}")
self.engine.runAndWait()

Наконец, я тоже попробовал войти в систему, тоже получил те же ошибки:

class App(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Initialize pyttsx3 with 'sapi5' engine and suppress debug logs
self.engine = pyttsx3.init(driverName='sapi5')
logging.getLogger('pyttsx3').setLevel(logging.WARNING)
Im not really sure why these errors are happening anymore, should i use a different tts module? P

пожалуйста, помогите мне! Спасибо!!!
Для справки, это весь мой код, без pyttsx3:
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDRaisedButton
from kivy.graphics.texture import Texture
from kivy.uix.image import Image
from kivy.clock import Clock
import cv2
import mediapipe as mp
import numpy as np

mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

class App(MDApp):
def build(self):
layout = MDBoxLayout(orientation='vertical')
self.image = Image()
layout.add_widget(self.image)
layout.add_widget(MDRaisedButton(
text="Go Back",
pos_hint={'center_x': .5, 'center_y': .5},
size_hint=(None, None))
)

# Initialize OpenCV video capture
self.capture = cv2.VideoCapture(0)

# Initialize Mediapipe pose detection
self.pose = mp_pose.Pose(
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)

# Initialize push-up counter and related variables
self.counter = 0
self.stage = None
self.prev_stage = None

# Schedule the video loading function
Clock.schedule_interval(self.load_video, 1/30) # Adjust frame rate as needed
return layout

def calculate_angle(self, a, b, c):
a = np.array(a)
b = np.array(b)
c = np.array(c)
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
angle = np.abs(radians * 180.0 / np.pi)
if angle > 180.0:
angle = 360.0 - angle
return angle

def load_video(self, dt):
ret, frame = self.capture.read()
if ret:
# Run pose estimation
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = self.pose.process(image_rgb)

# Extract relevant landmarks for push-up detection
if results.pose_landmarks is not None:
landmarks = results.pose_landmarks.landmark
left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
left_elbow = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value]
right_elbow = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value]
left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value]
right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value]
left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
left_knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]
right_knee = landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]

# Calculate angles for push-up detection
angle_left = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_elbow.x, left_elbow.y],
[left_wrist.x, left_wrist.y])
angle_right = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_elbow.x, right_elbow.y],
[right_wrist.x, right_wrist.y])
angle2 = self.calculate_angle([left_shoulder.x, left_shoulder.y], [left_hip.x, left_hip.y],
[left_knee.x, left_knee.y])
angle3 = self.calculate_angle([right_shoulder.x, right_shoulder.y], [right_hip.x, right_hip.y],
[right_knee.x, right_knee.y])

# Update stage based on angle criteria
if angle_left < 90 and angle_right < 90 and angle2 > 165 and angle3 > 165:
self.stage = "down"
else:
self.stage = "up"

# Increment counter if criteria met
if self.stage == "up" and self.prev_stage == "down":
self.counter += 1

self.prev_stage = self.stage

# Display push-up counter on frame
cv2.putText(frame, f'Push-ups: {self.counter}', (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

# Convert frame to Kivy texture and display in Image widget
buffer = cv2.flip(frame, 0).tobytes()
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
texture.blit_buffer(buffer, colorfmt='bgr', bufferfmt='ubyte')
self.image.texture = texture

def on_stop(self):
# Release OpenCV video capture and Mediapipe pose
self.capture.release()
self.pose.close()
super().on_stop()

if __name__ == '__main__':
App().run()


Подробнее здесь: https://stackoverflow.com/questions/786 ... eed-freeze

Вернуться в «Python»