diff --git a/app.py b/app.py new file mode 100644 index 0000000..566eaee --- /dev/null +++ b/app.py @@ -0,0 +1,38 @@ +import json +import uuid +import websocket +from flask import Flask, request, jsonify +import sys +import openpose_gen as opg + +sys.path.append('./') + +app = Flask(__name__) + +@app.route('/coordinates', methods=['POST']) +def receive_coordinates(): + if request.is_json: + data = request.get_json() + coordinates = data['coordinates'] + canvas_size = data['canvas_size'] + + if not coordinates or not canvas_size: + return jsonify({"status": "error", "message": "Missing data"}), 422 + + opg.save_bodypose(canvas_size, canvas_size, coordinates) + + return jsonify({"status": "success", "message": "Data received"}), 201 + else: + return jsonify({"status": "error", "message": "Request must be JSON"}), 415 + +def open_websocket_connection(): + server_address='127.0.0.1:8188' + client_id=str(uuid.uuid4()) + ws = websocket.WebSocket() + ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id)) + return ws, server_address, client_id + + + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/openpose_gen.py b/openpose_gen.py index eb21585..8329585 100644 --- a/openpose_gen.py +++ b/openpose_gen.py @@ -4,6 +4,49 @@ from typing import List import math import cv2 +coco_limbSeq = [ + [2, 3], [2, 6], [3, 4], [4, 5], + [6, 7], [7, 8], [2, 9], [9, 10], + [10, 11], [2, 12], [12, 13], [13, 14], + [2, 1], [1, 15], [15, 17], [1, 16], + [16, 18], +] +coco_colors = [ + [255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0], + [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], + [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85] +] + +body_25_limbSeq = [ + [1, 8], [1, 2], [1, 5], [2, 3], + [3, 4], [5, 6], [6, 7], [8, 9], + [9, 10], [10, 11], [8, 12], [12, 13], + [13, 14], [1, 0], [0, 15], [15, 17], + [0, 16], [16, 18], [14, 19], [19, 20], + [14, 21], [11, 22], [22, 23], [11, 24] +] +body_25_colors = [ + [255, 0, 85], [255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], + [0, 255, 0], [255, 0, 0], [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], + [0, 0, 255], [255, 0, 170], [170, 0, 255], [255, 0, 255], [85, 0, 255], [0, 0, 255], [0, 0, 255], + [0, 0, 255], [0, 0, 255], [0, 255, 255], [0, 255, 255], [0, 255, 255] +] + +body_25B_limbSeq = [ + [0, 1], [0, 2], [1, 3], [2, 4], [5, 7], [6, 8], [7, 9], [8, 10], + [5, 11], [6, 12], [11, 13], [12, 14], [13, 15], [14, 16], [15, 19], + [19, 20], [15, 21], [16, 22], [22, 23], [16, 24], [5, 17], [6, 17], + [17, 18], [11, 12] +] + +body_25B_colors = [ + [255, 0, 85], [170, 0, 255], [255, 0, 170], [85, 0, 255], [255, 0, 255], + [170, 255, 0], [255, 85, 0], [85, 255, 0], [255, 170, 0], [0, 255, 0], + [255, 255, 0], [0, 170, 255], [0, 255, 85], [0, 85, 255], [0, 255, 170], + [0, 0, 255], [0, 255, 255], [255, 0, 0], [255, 0, 0], [0, 0, 255], + [0, 0, 255], [0, 0, 255], [0, 255, 255], [0, 255, 255], [0, 255, 255] +] + class Keypoint: def __init__(self, x: float, y: float, confidence: float = 1.0): """ @@ -21,22 +64,37 @@ class Keypoint: def __repr__(self): return f"Keypoint(x={self.x}, y={self.y}, confidence={self.confidence})" +class Skeleton: + def __init__(self, keypoints: List[Keypoint]): + self.keypoints = keypoints + + def __repr__(self): + return f"Skeleton(keypoints={self.keypoints})" + +class Skeleton_Seqence: + def __init__(self, skeletons: List[Skeleton]): + self.skeletons = skeletons + + def __repr__(self): + return f"Skeleton_Seqence(Skeleton_frames={self.skeletons})" + + def get_frame(self, frame_index: int) -> Skeleton: + return self.skeletons[frame_index] + + def add_frame(self, skeleton: Skeleton): + self.skeletons.append(skeleton) + +def get_time_slice_for_Skeleton_Seqences(skeleton_seqences: List[Skeleton_Seqence], frame_index: int) -> List[Skeleton]: + return [skeleton_seq.get_frame(frame_index) for skeleton_seq in skeleton_seqences] + + def is_normalized(keypoints: List[Keypoint]) -> bool: - """ - Check if the keypoints are normalized between 0 and 1. - - Args: - keypoints (List[Keypoint]): A list of Keypoint objects. - - Returns: - bool: True if all keypoints are normalized, False otherwise. - """ for keypoint in keypoints: if not (0 <= keypoint.x <= 1 and 0 <= keypoint.y <= 1): return False return True -def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint], xinsr_stick_scaling: bool = False) -> np.ndarray: +def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint], limbSeq, colors, xinsr_stick_scaling: bool = False) -> np.ndarray: """ Draw keypoints and limbs representing body pose on a given canvas. @@ -66,18 +124,6 @@ def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint], xinsr_stick_sca else: stick_scale = 1 - limbSeq = [ - [2, 3], [2, 6], [3, 4], [4, 5], - [6, 7], [7, 8], [2, 9], [9, 10], - [10, 11], [2, 12], [12, 13], [13, 14], - [2, 1], [1, 15], [15, 17], [1, 16], - [16, 18], - ] - - colors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0], \ - [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], \ - [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85]] - for (k1_index, k2_index), color in zip(limbSeq, colors): keypoint1 = keypoints[k1_index - 1] keypoint2 = keypoints[k2_index - 1] @@ -105,50 +151,55 @@ def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint], xinsr_stick_sca return canvas -def openpose_json_to_keypoints(json_file: str) -> List[Keypoint]: - """ - Convert OpenPose JSON file to a list of Keypoint objects. - - Args: - json_file (str): The path to the OpenPose JSON file. - - Returns: - List[Keypoint]: A list of Keypoint objects representing the keypoints extracted from the JSON file. - """ +def json_to_keypoints_openpose(json_file: str) -> List[Keypoint]: with open(json_file, 'r') as file: data = json.load(file) keypoints = data[0]['people'][0]['pose_keypoints_2d'] keypoints = [Keypoint(keypoints[i], keypoints[i + 1]) for i in range(0, len(keypoints), 3)] return keypoints +def coordinates_to_keypoints(coordinates: list) -> List[Keypoint]: + keypoints = [Keypoint(coordinates[i], coordinates[i + 1]) for i in range(0, len(coordinates), 3)] + return keypoints + +def save_bodypose(width: int, height: int, coordinates: list): + if not hasattr(save_bodypose, 'counter'): + save_bodypose.counter = 0 # Initialize the counter attribute + + canvas = np.zeros((height, width, 3), dtype=np.uint8) + keypoints = coordinates_to_keypoints(coordinates) + canvas = draw_bodypose(canvas, keypoints, coco_limbSeq, coco_colors) + + # Save as body_pose_output0000.png, body_pose_output0001.png, ... + cv2.imwrite('body_pose_output%04d.png' % save_bodypose.counter, canvas) + save_bodypose.counter += 1 # Increment the counter + +def array_json_to_Skeleton_Seqences(json_file: str) -> List[Skeleton_Seqence]: + with open(json_file, 'r') as file: + data = json.load(file) + + skeleton_sequences = [] + for frame in data: + for i in range(len(frame)): + while len(skeleton_sequences) <= i: + skeleton_sequences.append(None) + skeleton_sequences[i] = Skeleton_Seqence([]) + skeleton = Skeleton([Keypoint(keypoint[0], keypoint[1], keypoint[2]) for keypoint in frame[i]]) + skeleton_sequences[i].add_frame(skeleton) + return skeleton_sequences + def main(): - # Create a blank canvas - canvas = np.zeros((768, 768, 3), dtype=np.uint8) + json_file = '0001_002_00_01_1.json' + image_path = 'test' + skeleton_sequences = array_json_to_Skeleton_Seqences(json_file) + for i in range(20): + sliced = get_time_slice_for_Skeleton_Seqences(skeleton_sequences, i) + canvas = np.zeros((480, 640, 3), dtype=np.uint8) + for skeleton in sliced: + keypoints = skeleton.keypoints + canvas = draw_bodypose(canvas, keypoints, body_25B_limbSeq, body_25B_colors) - # Load the keypoints from the OpenPose JSON file - keypoints = openpose_json_to_keypoints('openpose_output.json') + cv2.imwrite(image_path + '_' + str(i) + '.png', canvas) - # Draw the body pose on the canvas - canvas = draw_bodypose(canvas, keypoints) - - # Display the result - cv2.imshow('Body Pose', canvas) - cv2.waitKey(0) - cv2.destroyAllWindows() - -if __name__ == "__main__": - main() - -# Here is an example of input json file, create a List of Keypoint objects from the json file and draw the body pose on a canvas using the draw_bodypose function. -# -# [ -# { -# "people": [ -# { -# "pose_keypoints_2d": [423.575046753433, 113.537678172812, 1, 378.126093103822, 185.044031914867, 1, 416.303214169495, 169.288394649668, 1, 470.841958549029, 122.021482854073, 1, 519.320842441947, 48.0911849173717, 1, 339.948972038149, 200.799669180065, 1, 322.981362675627, 289.273632284642, 1, 316.921502189012, 391.079288459771, 1, 439.330684018632, 363.203930221343, 1, 412.667297877527, 541.363828527819, 1, 375.096162860515, 702.556117471773, 1, 375.096162860515, 364.415902318666, 1, 359.340525595316, 530.456079651912, 1, 292.682060242553, 674.680759233345, 1, 411.455325780204, 105.053873491551, 1, 418.727158364141, 102.629929296905, 1, 383.579967541775, 120.80951075675, 1, 371.460246568546, 122.021482854073, 1] -# } -# ], -# "canvas_height": 768, -# "canvas_width": 768 -# } -# ] \ No newline at end of file +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/openpose_output.json b/openpose_output.json index a3a74f1..02933f4 100644 --- a/openpose_output.json +++ b/openpose_output.json @@ -1,11 +1,11 @@ [ - { - "people": [ - { - "pose_keypoints_2d": [423.575046753433, 113.537678172812, 1, 378.126093103822, 185.044031914867, 1, 416.303214169495, 169.288394649668, 1, 470.841958549029, 122.021482854073, 1, 519.320842441947, 48.0911849173717, 1, 339.948972038149, 200.799669180065, 1, 322.981362675627, 289.273632284642, 1, 316.921502189012, 391.079288459771, 1, 439.330684018632, 363.203930221343, 1, 412.667297877527, 541.363828527819, 1, 375.096162860515, 702.556117471773, 1, 375.096162860515, 364.415902318666, 1, 359.340525595316, 530.456079651912, 1, 292.682060242553, 674.680759233345, 1, 411.455325780204, 105.053873491551, 1, 418.727158364141, 102.629929296905, 1, 383.579967541775, 120.80951075675, 1, 371.460246568546, 122.021482854073, 1] - } - ], - "canvas_height": 768, - "canvas_width": 768 - } -] \ No newline at end of file + { + "people": [ + { + "pose_keypoints_2d": [380.717502117157, 102.982418060303, 1, 386.65306571126, 210.482069820166, 1, 312.128767251968, 211.141576886177, 1, 211.883693218231, 224.331718206406, 1, 153.847071409225, 128.043686568737, 1, 461.177364170551, 209.822562754154, 1, 570.655537128449, 217.736647546291, 1, 606.268918693066, 122.767630040646, 1, 326.63792270422, 457.797219574451, 1, 296.300597667694, 662.244410037994, 1, 277.834399819374, 765.127512335777, 1, 438.754123926163, 457.797219574451, 1, 487.557646811008, 653.011311113834, 1, 533.723141431809, 763.808498203754, 1, 367.527360796928, 93.7493191361427, 1, 396.545671701431, 92.4303050041199, 1, 349.061162948608, 114.853545248508, 1, 421.606940209866, 113.534531116486, 1] + } + ], + "canvas_height": 768, + "canvas_width": 768 + } + ] \ No newline at end of file