Bachstelze commited on
Commit
d11b9f9
·
1 Parent(s): 796297a

test saving

Browse files
Files changed (2) hide show
  1. app.py +141 -6
  2. requirements.txt +2 -0
app.py CHANGED
@@ -1,11 +1,87 @@
1
  from PIL import Image
2
  import gradio as gr
3
  from controlnet_aux import OpenposeDetector
 
 
 
 
 
4
 
5
  # Load OpenPose detector
6
  openpose = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
7
 
8
- def generate_pose(image, use_openpose=True):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  img = image.convert("RGB")
10
  if use_openpose:
11
  result = openpose(img)
@@ -13,18 +89,77 @@ def generate_pose(image, use_openpose=True):
13
  result = img
14
  if not isinstance(result, Image.Image):
15
  result = Image.fromarray(result)
16
- return result
17
 
18
- # Gradio UI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  demo = gr.Interface(
20
- fn=generate_pose,
21
  inputs=[
22
  gr.Image(type="pil", label="Upload Image"),
23
  gr.Checkbox(value=True, label="Use OpenPose (default: true)"),
24
  ],
25
- outputs=gr.Image(type="pil", label="Pose Output"),
 
 
 
26
  title="OpenPose Pose Generator",
27
- description="Generate full body pose including face and hands."
28
  )
29
 
30
  if __name__ == "__main__":
 
1
  from PIL import Image
2
  import gradio as gr
3
  from controlnet_aux import OpenposeDetector
4
+ import json
5
+ import csv
6
+ import os
7
+ from datetime import datetime
8
+ from typing import Dict, List, Any
9
 
10
  # Load OpenPose detector
11
  openpose = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
12
 
13
+ def extract_joint_positions(openpose_result) -> Dict[str, Any]:
14
+ """Extract joint positions from OpenPose result."""
15
+ # OpenPose returns a PIL Image with encoded pose data
16
+ # We need to access the pose data from the result
17
+ if hasattr(openpose_result, 'pose_keypoints_2d'):
18
+ # If OpenPose returns structured data
19
+ return {
20
+ "keypoints": openpose_result.pose_keypoints_2d,
21
+ "timestamp": datetime.now().isoformat()
22
+ }
23
+ else:
24
+ # Fallback: extract from image if possible
25
+ return {
26
+ "keypoints": [],
27
+ "timestamp": datetime.now().isoformat(),
28
+ "note": "No structured pose data available"
29
+ }
30
+
31
+ def save_to_csv(joint_data: Dict[str, Any], filename: str = None) -> str:
32
+ """Save joint positions to CSV file."""
33
+ if filename is None:
34
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
35
+ filename = f"pose_data_{timestamp}.csv"
36
+
37
+ filepath = os.path.join("pose_outputs", filename)
38
+ os.makedirs("pose_outputs", exist_ok=True)
39
+
40
+ with open(filepath, 'w', newline='') as csvfile:
41
+ writer = csv.writer(csvfile)
42
+ writer.writerow(["Joint", "X", "Y", "Confidence"])
43
+
44
+ keypoints = joint_data.get("keypoints", [])
45
+ if keypoints and isinstance(keypoints, list):
46
+ # OpenPose format: [x1, y1, c1, x2, y2, c2, ...]
47
+ joint_names = [
48
+ "Nose", "Neck", "RShoulder", "RElbow", "RWrist",
49
+ "LShoulder", "LElbow", "LWrist", "RHip", "RKnee",
50
+ "RAnkle", "LHip", "LKnee", "LAnkle", "REye",
51
+ "LEye", "REar", "LEar", "LBigToe", "LSmallToe",
52
+ "LHeel", "RBigToe", "RSmallToe", "RHeel"
53
+ ]
54
+
55
+ for i in range(0, len(keypoints), 3):
56
+ if i + 2 < len(keypoints):
57
+ joint_idx = i // 3
58
+ joint_name = joint_names[joint_idx] if joint_idx < len(joint_names) else f"Joint_{joint_idx}"
59
+ writer.writerow([
60
+ joint_name,
61
+ keypoints[i], # X
62
+ keypoints[i + 1], # Y
63
+ keypoints[i + 2] # Confidence
64
+ ])
65
+
66
+ writer.writerow(["Timestamp", joint_data.get("timestamp", "")])
67
+
68
+ return filepath
69
+
70
+ def save_to_json(joint_data: Dict[str, Any], filename: str = None) -> str:
71
+ """Save joint positions to JSON file."""
72
+ if filename is None:
73
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
74
+ filename = f"pose_data_{timestamp}.json"
75
+
76
+ filepath = os.path.join("pose_outputs", filename)
77
+ os.makedirs("pose_outputs", exist_ok=True)
78
+
79
+ with open(filepath, 'w') as jsonfile:
80
+ json.dump(joint_data, jsonfile, indent=2)
81
+
82
+ return filepath
83
+
84
+ def generate_pose(image, use_openpose=True, save_outputs=True):
85
  img = image.convert("RGB")
86
  if use_openpose:
87
  result = openpose(img)
 
89
  result = img
90
  if not isinstance(result, Image.Image):
91
  result = Image.fromarray(result)
 
92
 
93
+ # Extract and save pose data if OpenPose was used
94
+ joint_data = {}
95
+ if use_openpose and save_outputs:
96
+ joint_data = extract_joint_positions(result)
97
+ csv_path = save_to_csv(joint_data)
98
+ json_path = save_to_json(joint_data)
99
+ joint_data["csv_path"] = csv_path
100
+ joint_data["json_path"] = json_path
101
+
102
+ return result, joint_data
103
+
104
+ # Gradio UI with pose data outputs
105
+ def format_pose_output(joint_data: Dict[str, Any]) -> str:
106
+ """Format pose data for display."""
107
+ if not joint_data or not joint_data.get("keypoints"):
108
+ return "No pose data available."
109
+
110
+ output = "### Joint Positions\n\n"
111
+ output += f"**Timestamp:** {joint_data.get('timestamp', 'N/A')}\n\n"
112
+
113
+ keypoints = joint_data.get("keypoints", [])
114
+ if keypoints and isinstance(keypoints, list):
115
+ joint_names = [
116
+ "Nose", "Neck", "RShoulder", "RElbow", "RWrist",
117
+ "LShoulder", "LElbow", "LWrist", "RHip", "RKnee",
118
+ "RAnkle", "LHip", "LKnee", "LAnkle", "REye",
119
+ "LEye", "REar", "LEar", "LBigToe", "LSmallToe",
120
+ "LHeel", "RBigToe", "RSmallToe", "RHeel"
121
+ ]
122
+
123
+ output += "| Joint | X | Y | Confidence |\n"
124
+ output += "|-------|---|---|------------|\n"
125
+
126
+ for i in range(0, min(len(keypoints), 72), 3):
127
+ if i + 2 < len(keypoints):
128
+ joint_idx = i // 3
129
+ joint_name = joint_names[joint_idx] if joint_idx < len(joint_names) else f"Joint_{joint_idx}"
130
+ x = keypoints[i]
131
+ y = keypoints[i + 1]
132
+ confidence = keypoints[i + 2]
133
+ output += f"| {joint_name} | {x:.1f} | {y:.1f} | {confidence:.3f} |\n"
134
+
135
+ output += f"\n**CSV File:** `{joint_data.get('csv_path', 'N/A')}`\n"
136
+ output += f"**JSON File:** `{joint_data.get('json_path', 'N/A')}`\n"
137
+
138
+ return output
139
+
140
+ def process_and_display(image, use_openpose=True):
141
+ """Process image and return pose output with data files."""
142
+ result, joint_data = generate_pose(image, use_openpose, save_outputs=True)
143
+
144
+ if use_openpose and joint_data:
145
+ pose_info = format_pose_output(joint_data)
146
+ return result, pose_info
147
+ else:
148
+ return result, "Pose data extraction skipped."
149
+
150
+ # Gradio UI with pose data outputs
151
  demo = gr.Interface(
152
+ fn=process_and_display,
153
  inputs=[
154
  gr.Image(type="pil", label="Upload Image"),
155
  gr.Checkbox(value=True, label="Use OpenPose (default: true)"),
156
  ],
157
+ outputs=[
158
+ gr.Image(type="pil", label="Pose Output"),
159
+ gr.Textbox(label="Pose Data", lines=10)
160
+ ],
161
  title="OpenPose Pose Generator",
162
+ description="Generate full body pose including face and hands. Extracts and stores joint positions in CSV and JSON formats."
163
  )
164
 
165
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -10,3 +10,5 @@ lightgbm==4.6.0
10
 
11
  pytest==8.3.4
12
  pytest-cov==6.0.0
 
 
 
10
 
11
  pytest==8.3.4
12
  pytest-cov==6.0.0
13
+
14
+ controlnet-aux==0.0.6