|
|
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 |
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
self.current_skeleton = None |
|
|
self.suggested_save_path = "" |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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) |
|
|
) |
|
|
|
|
|
|
|
|
base_name, _ = os.path.splitext(file_path) |
|
|
self.suggested_save_path = f"{base_name}_pose.png" |
|
|
|
|
|
|
|
|
preview_rgb = cv2.cvtColor(self.current_skeleton, cv2.COLOR_BGR2RGB) |
|
|
pil_img = Image.fromarray(preview_rgb) |
|
|
pil_img.thumbnail((600, 600)) |
|
|
|
|
|
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) |
|
|
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() |
|
|
|
|
|
|