File size: 3,593 Bytes
6998c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import tkinter as tk
from tkinter import filedialog, messagebox
import cv2
import mediapipe as mp
import numpy as np
import os
from PIL import Image, ImageTk

# Initialize MediaPipe Pose
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.5)

class PoseApp:
    def __init__(self, root):
        self.root = root
        self.root.title("OpenPose Maker with Preview")
        self.root.geometry("700x850")
        
        # Variables to hold data
        self.current_skeleton = None
        self.suggested_save_path = ""

        # UI Elements
        self.btn_load = tk.Button(root, text="Step 1: Load Photo", command=self.process_image, 
                                  bg="#4285F4", fg="white", font=('Arial', 11, 'bold'), pady=10)
        self.btn_load.pack(pady=10)

        self.preview_label = tk.Label(root, text="[ Image Preview Area ]", bg="gray90")
        self.preview_label.pack(pady=10, fill=tk.BOTH, expand=True)

        self.status_label = tk.Label(root, text="Ready", fg="gray")
        self.status_label.pack()

        self.btn_save = tk.Button(root, text="Step 2: Save This Pose", command=self.save_image, 
                                  bg="#0F9D58", fg="white", font=('Arial', 11, 'bold'), pady=10, state=tk.DISABLED)
        self.btn_save.pack(pady=20)

    def process_image(self):
        file_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.jpg *.jpeg *.png")])
        if not file_path: return

        image = cv2.imread(file_path)
        if image is None: return
        
        # Process Pose
        image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        results = pose.process(image_rgb)
        
        h, w, _ = image.shape
        self.current_skeleton = np.zeros((h, w, 3), dtype=np.uint8)

        if results.pose_landmarks:
            mp_drawing.draw_landmarks(
                self.current_skeleton, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=5, circle_radius=4),
                mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=3)
            )

            # Prepare Auto-Save Path
            base_name, _ = os.path.splitext(file_path)
            self.suggested_save_path = f"{base_name}_pose.png"

            # Fix Tiny Preview: Resize for GUI (max 600px)
            preview_rgb = cv2.cvtColor(self.current_skeleton, cv2.COLOR_BGR2RGB)
            pil_img = Image.fromarray(preview_rgb)
            pil_img.thumbnail((600, 600)) # Resizes while keeping aspect ratio
            
            img_tk = ImageTk.PhotoImage(pil_img)
            self.preview_label.config(image=img_tk, text="")
            self.preview_label.image = img_tk
            
            self.btn_save.config(state=tk.NORMAL)
            self.status_label.config(text="Pose generated! Click Save to finish.", fg="blue")
        else:
            messagebox.showwarning("Error", "No person detected in this photo.")

    def save_image(self):
        if self.current_skeleton is not None and self.suggested_save_path:
            cv2.imwrite(self.suggested_save_path, self.current_skeleton)
            messagebox.showinfo("Saved!", f"File saved as:\n{os.path.basename(self.suggested_save_path)}")
            self.btn_save.config(state=tk.DISABLED) # Prevent double-saving
            self.status_label.config(text=f"Done: {os.path.basename(self.suggested_save_path)}", fg="green")

if __name__ == "__main__":
    root = tk.Tk()
    app = PoseApp(root)
    root.mainloop()