Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't run on Mac #6

Open
suyashcjoshi opened this issue Jan 27, 2024 · 3 comments
Open

Can't run on Mac #6

suyashcjoshi opened this issue Jan 27, 2024 · 3 comments

Comments

@suyashcjoshi
Copy link

I'm unable to run the python on Mac, the windows where you see the markers don't show up. Anyone else running into same problem or know a fix? I think it might have to do with threading but not sure.

@jerryum
Copy link

jerryum commented Feb 12, 2024

I have the same issue. I had to turn the debug mode off to skip the part to see the avatar's move.
This is a known issue of opencv - it doesn't support multi-threads in the MacOS. You should use the main thread in the MacOS.
opencv/opencv#22602

Traceback (most recent call last):
File "/opt/homebrew/Cellar/python@3.10/3.10.13_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/Users/jerrylee/Works/UnityPythonMediaPipeAvatar/mediapipeavatar/body.py", line 92, in run
cv2.imshow('Body Tracking', image)
cv2.error: Unknown C++ exception from OpenCV code

@jerryum
Copy link

jerryum commented Feb 12, 2024

FYI, you can add main_for_mac.py with the code. No multi-thread and it works in MacOS.

import mediapipe as mp
import cv2
import time
import global_vars
import struct
from clientUDP import ClientUDP

class BodyTracker:
    def __init__(self):
        self.cap = None
        self.client = None
        self.pipe = None
        self.data = ""

    def setup_capture(self):
        self.cap = cv2.VideoCapture(global_vars.CAM_INDEX)
        if global_vars.USE_CUSTOM_CAM_SETTINGS:
            self.cap.set(cv2.CAP_PROP_FPS, global_vars.FPS)
            self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, global_vars.WIDTH)
            self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, global_vars.HEIGHT)
        print("Opened Capture @ %s fps" % str(self.cap.get(cv2.CAP_PROP_FPS)))

    def run(self):
        self.setup_capture()
        self.setup_comms()

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

        with mp_pose.Pose(min_detection_confidence=0.80, min_tracking_confidence=0.5, model_complexity=global_vars.MODEL_COMPLEXITY, static_image_mode=False, enable_segmentation=True) as pose:
            while True:
                ret, frame = self.cap.read()
                if not ret:
                    break

                # Image transformations
                frame = cv2.flip(frame, 1)
                frame.flags.writeable = global_vars.DEBUG
                
                # Process the image
                results = pose.process(frame)

                # Render results
                if global_vars.DEBUG:
                    if results.pose_landmarks:
                        mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                                                  mp_drawing.DrawingSpec(color=(255, 100, 0), thickness=2, circle_radius=4),
                                                  mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2, circle_radius=2))
                    cv2.imshow('Body Tracking', frame)
                    if cv2.waitKey(3) & 0xFF == 27:
                        break

                # Prepare and send data
                self.prepare_data(results)
                self.send_data(self.data)

        self.cleanup()

    def prepare_data(self, results):
        self.data = ""
        if results.pose_world_landmarks:
            for i in range(0, 33):
                landmark = results.pose_world_landmarks.landmark[i]
                self.data += "{}|{}|{}|{}\n".format(i, landmark.x, landmark.y, landmark.z)

    def setup_comms(self):
        if not global_vars.USE_LEGACY_PIPES:
            self.client = ClientUDP(global_vars.HOST, global_vars.PORT)
            self.client.start()
        else:
            print("Using Pipes for interprocess communication (not supported on OSX or Linux).")

    def send_data(self, message):
        if not global_vars.USE_LEGACY_PIPES:
            self.client.sendMessage(message)
        else:
            # this is for MacOs. 
            print("Using Pipes for interprocess communication (not supported on OSX or Linux).")
            pass  

    def cleanup(self):
        if self.cap:
            self.cap.release()
        cv2.destroyAllWindows()
        if self.pipe:
            self.pipe.close()

if __name__ == "__main__":
    tracker = BodyTracker()
    tracker.run()

@ganeshsar
Copy link
Owner

This is great thanks for clarifying that this issue was related to multi-threading. I will try to create an update for the project at some point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants