deteksi-badan-new/tampilkan_json.py

129 lines
4.5 KiB
Python

import cv2
import json
import mediapipe as mp
import numpy as np
from scipy.spatial import distance
# Load JSON data
with open('data_yoga.json') as f:
data = json.load(f)
image_name = "Camel"
image = None
# Extract landmarks from JSON data
landmarks_from_json = []
the_landmarks = None
# Load the image
for the_data in data:
if the_data['name'] == image_name:
for lm in the_data['landmarks']:
landmarks_from_json.append([lm['coordinates'][0], lm['coordinates'][1]])
the_landmarks = the_data['landmarks']
image = cv2.imread(the_data['image_name'])
# Initialize MediaPipe pose module
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
# Function to calculate similarity between two sets of landmarks
def calculate_similarity(landmarks1, landmarks2):
if not landmarks1 or not landmarks2:
return 0
# Normalize landmarks
norm_landmarks1 = np.array(landmarks1) - np.mean(landmarks1, axis=0)
norm_landmarks2 = np.array(landmarks2) - np.mean(landmarks2, axis=0)
# Calculate the distance between corresponding landmarks
dists = [distance.euclidean(lm1, lm2) for lm1, lm2 in zip(norm_landmarks1, norm_landmarks2)]
# Calculate similarity as the inverse of the average distance
similarity = 1 / (1 + np.mean(dists))
return similarity * 100
# Draw landmarks and connections on the image
def draw_landmarks(image, landmarks):
annotated_image = image.copy()
for landmark in landmarks:
# Extract landmark coordinates
landmark_x = int(landmark['coordinates'][0] * annotated_image.shape[1])
landmark_y = int(landmark['coordinates'][1] * annotated_image.shape[0])
# Draw a circle at the landmark position
cv2.circle(annotated_image, (landmark_x, landmark_y), 5, (0, 255, 0), -1)
# Add text with the body part label
cv2.putText(annotated_image, landmark['body'], (landmark_x, landmark_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(255, 255, 255), 1)
# Draw connections between landmarks
connections = mp_pose.POSE_CONNECTIONS
for connection in connections:
start_idx = connection[0]
end_idx = connection[1]
if 0 <= start_idx < len(landmarks) and 0 <= end_idx < len(landmarks):
start_landmark = landmarks[start_idx]['coordinates']
end_landmark = landmarks[end_idx]['coordinates']
start_x = int(start_landmark[0] * annotated_image.shape[1])
start_y = int(start_landmark[1] * annotated_image.shape[0])
end_x = int(end_landmark[0] * annotated_image.shape[1])
end_y = int(end_landmark[1] * annotated_image.shape[0])
cv2.line(annotated_image, (start_x, start_y), (end_x, end_y), (0, 255, 0), 2)
return annotated_image
# Annotate and display the image
annotated_image = draw_landmarks(image, the_landmarks)
cv2.imshow('Image with Landmarks and Connections', annotated_image)
# Open webcam
cap = cv2.VideoCapture(0)
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Convert the BGR image to RGB
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image_rgb.flags.writeable = False
# Process the image and detect the pose
results = pose.process(image_rgb)
# Convert the RGB image back to BGR
image_rgb.flags.writeable = True
image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
# Draw the pose annotation on the image
if results.pose_landmarks:
mp_drawing.draw_landmarks(
image_bgr,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2, circle_radius=2),
)
# Extract landmarks
landmarks_from_webcam = []
for lm in results.pose_landmarks.landmark:
landmarks_from_webcam.append([lm.x, lm.y])
# Calculate similarity
similarity = calculate_similarity(landmarks_from_json, landmarks_from_webcam)
cv2.putText(image_bgr, f'Similarity: {similarity:.2f}%', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# Display the image
cv2.imshow('Webcam Pose', image_bgr)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
# Release resources
cap.release()
cv2.destroyAllWindows()
cv2.waitKey(1)