あとは標準出力からシリアルポートに出力先を変更するだけです。Bluetooth接続されたポート番号をプログラム内に記入してください。

import serial
pre_angle_s = 0
ser = serial.Serial(‘COM5’, 115200) #ポート番号と速度は環境に合わせて変更
…..
ser.write(str.encode(str(int(angle_s))+”\n”))
….
ser.close()

などを追加します。ある程度検出角度の変化があった場合に値を送信するようにしておくと、サーボが忙しく動きません。次の例では、1ステップ前の値と5より大きな差があればサーボに数値を送るようにしています。

import cv2
import math
import mediapipe as mp
import serial

mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose
pre_angle_s = 0
ser = serial.Serial('COM5', 115200)

cap = cv2.VideoCapture(1)
with mp_pose.Pose(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5) as pose:
  while cap.isOpened():
    success, image = cap.read()
    if not success:
      print("Ignoring empty camera frame.")
      continue

    image.flags.writeable = False
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = pose.process(image)

    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    mp_drawing.draw_landmarks(
        image,
        results.pose_landmarks,
        mp_pose.POSE_CONNECTIONS,
        landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())
    if results.pose_landmarks:
      x1=results.pose_landmarks.landmark[12].x #x1,y1 = shoulder
      x2=results.pose_landmarks.landmark[14].x #x2,y2 = elbow
      y1=results.pose_landmarks.landmark[12].y
      y2=results.pose_landmarks.landmark[14].y
      
      if x2<x1:
        angle_s = int(math.degrees(math.atan((y2-y1)/(x1-x2))))
      else:# x2>=x1
        angle_s = int(180+math.degrees(math.atan((y2-y1)/(x1-x2))))

      if angle_s < 0:
        angle_s = 0
      elif angle_s > 180:
        angle_s = 180

      #print("\r"+str(angle_s))

      #Bluetoothで送信
      if abs(angle_s-pre_angle_s)>5:
        ser.write(str.encode(str(angle_s)+"\n"))
        pre_angle_s = angle_s


    cv2.imshow('SIGACI', cv2.flip(image, 1))
    if cv2.waitKey(5) & 0xFF == 27: #ESCで終了
      break
cap.release()
ser.close()