Compare commits

..

2 Commits

Author SHA1 Message Date
0729d20a6b update code 2024-06-18 23:39:03 +05:30
5c4136cf6b refactor: add missing interpolators for the string in logging 2024-06-17 14:40:21 +05:30
4 changed files with 244 additions and 182 deletions

BIN
binary_classified_image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

View File

@ -1,5 +1,7 @@
import warnings import warnings
import os import os
from tabulate import tabulate
import math
warnings.filterwarnings("ignore", warnings.filterwarnings("ignore",
category=UserWarning, category=UserWarning,
@ -8,7 +10,6 @@ warnings.filterwarnings("ignore",
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
import argparse import argparse
import math
import cv2 import cv2
from mediapipe.python.solutions import pose from mediapipe.python.solutions import pose
import logging import logging
@ -100,17 +101,17 @@ class Landmarker:
def run(self): def run(self):
logging.warning("person's height: ", self.person_height) logging.warning("person's height: %s", self.person_height)
logging.warning("person's pixel height: ", self.pixel_height) logging.warning("person's pixel height: %s", self.pixel_height)
front_results = self.process_images() front_results, side_results = self.process_images()
self.get_center_top_point(front_results) self.get_center_top_point(front_results)
self.calculate_distance_betn_landmarks(front_results) self.calculate_distance_betn_landmarks(front_results)
self.print_distance() self.output()
self.display_images() self.display_images()
@ -137,23 +138,12 @@ class Landmarker:
side_results.pose_landmarks, # type: ignore# type: ignore side_results.pose_landmarks, # type: ignore# type: ignore
self.landmarks_indices, self.landmarks_indices,
) )
return front_results return front_results, side_results
def calculate_distance(self, landmark1, landmark2):
l1 = landmark1.x, landmark1.y
l1 = int(l1[0] * self.resized_height), int(l1[1] * self.resized_width)
x1, y1 = l1
l2 = landmark2.x, landmark2.y
l2 = int(l2[0] * self.resized_height), int(l2[1] * self.resized_width)
x2, y2 = l2
pixel_distance = self.euclidean_distance(x1, x2, y1, y2)
real_distance = pixel_distance * self.pixel_to_metric_ratio()
return real_distance
def pixel_to_metric_ratio(self): def pixel_to_metric_ratio(self):
self.pixel_height = self.pixel_distance * 2 self.pixel_height = self.pixel_distance * 2
pixel_to_metric_ratio = self.person_height / self.pixel_height pixel_to_metric_ratio = self.person_height / self.pixel_height
logging.warning("pixel_to_metric_ratio", pixel_to_metric_ratio) logging.warning("pixel_to_metric_ratio %s", pixel_to_metric_ratio)
return pixel_to_metric_ratio return pixel_to_metric_ratio
def draw_landmarks(self, image, landmarks, indices): def draw_landmarks(self, image, landmarks, indices):
@ -166,53 +156,59 @@ class Landmarker:
def circle(self, image, cx, cy): def circle(self, image, cx, cy):
return cv2.circle(image, (cx, cy), 2, (255, 0, 0), -1) return cv2.circle(image, (cx, cy), 2, (255, 0, 0), -1)
def print_distance(self): def output(self):
print( table = [[
"Distance between left shoulder and left elbow:", "shoulder_elbow",
self.distance_left_hand_up, ], [
) "elbow_wrist",
], [
"hip_knee",
], [
"knee_ankel",
]]
output = tabulate(table,
headers=["measurement", "value"],
tablefmt="plain")
print(output)
print( def get_landmarks(self):
"Distance between left elbow and left wrist:", self.landmarks_to_calculate = [[
self.distance_left_hand_down, pose.PoseLandmark.LEFT_SHOULDER, pose.PoseLandmark.LEFT_ELBOW,
) pose.PoseLandmark.LEFT_WRIST
],
[
pose.PoseLandmark.LEFT_HIP,
pose.PoseLandmark.LEFT_KNEE,
pose.PoseLandmark.LEFT_ANKLE
]]
#return
print("Distance between left hip and left knee:", def calculate_distance_betn_landmarks(self, front_results, landmarks=[]):
self.distance_left_leg_up)
print("Distance between left knee and left ankle:",
self.distance_left_leg_down)
print("Distance between center and top point:", self.distance)
print("Height of person:", self.distance * 2)
def calculate_distance_betn_landmarks(self, front_results):
if not front_results.pose_landmarks: if not front_results.pose_landmarks:
return return
landmarks = front_results.pose_landmarks.landmark landmarks = front_results.pose_landmarks.landmark
landmarks_to_calculate = [
pose.PoseLandmark.LEFT_SHOULDER, pose.PoseLandmark.LEFT_ELBOW,
pose.PoseLandmark.LEFT_WRIST
]
#landmarks_to_calculate = self.get_landmarks();
for l in landmarks_to_calculate:
#l1 = int(l1[0] * self.resized_height), int(l1[1] * self.resized_width)
real_distance = 0
for idx, l in enumerate(landmarks_to_calculate):
if idx < len(landmarks_to_calculate) - 1:
_current = landmarks[l.value]
_nextl = landmarks_to_calculate[idx + 1]
_next = landmarks[_nextl.value]
pixel_distance = self.euclidean_distance(
_current.x, _current.y, _next.x, _next.y)
print(pixel_distance)
real_distance += pixel_distance * self.pixel_to_metric_ratio(
)
print(real_distance)
shoulder_left = landmarks[pose.PoseLandmark.LEFT_SHOULDER.value] def euclidean_distance(self, x1, y1, x2, y2):
elbow_left = landmarks[pose.PoseLandmark.LEFT_ELBOW.value]
wrist_left = landmarks[pose.PoseLandmark.LEFT_WRIST.value]
hip_left = landmarks[pose.PoseLandmark.LEFT_HIP.value]
knee_left = landmarks[pose.PoseLandmark.LEFT_KNEE.value]
ankle_left = landmarks[pose.PoseLandmark.LEFT_ANKLE.value]
self.distance_left_hand_up = self.calculate_distance(
shoulder_left, elbow_left)
self.distance_left_hand_down = self.calculate_distance(
elbow_left, wrist_left)
self.distance_left_leg_up = self.calculate_distance(
hip_left, knee_left)
self.distance_left_leg_down = self.calculate_distance(
knee_left, ankle_left)
def euclidean_distance(self, x1, x2, y1, y2):
distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
return distance return distance
@ -243,8 +239,8 @@ class Landmarker:
xt, yt = self.topmost_point xt, yt = self.topmost_point
self.circle(self.side_image_keypoints, xt, yt) self.circle(self.side_image_keypoints, xt, yt)
logging.warning("xt: ", xt) logging.warning("xt: %s", xt)
logging.warning(f"yt: ") logging.warning("yt: %s", yt)
xc, yc = None, None xc, yc = None, None
landmarks = side_results.pose_landmarks.landmark landmarks = side_results.pose_landmarks.landmark
@ -260,13 +256,14 @@ class Landmarker:
int(center_point[1] * self.side_image_resized.shape[0]), int(center_point[1] * self.side_image_resized.shape[0]),
) )
xc, yc = center_point xc, yc = center_point
logging.warning("xc: ", xc) logging.warning("xc: %s", xc)
logging.warning(f"yc: {yc}") logging.warning("yc: %s", yc)
self.circle(self.side_image_keypoints, xc, yc) self.circle(self.side_image_keypoints, xc, yc)
self.pixel_distance = self.euclidean_distance(xc, xt, yc, yt) self.pixel_distance = self.euclidean_distance(xc, xt, yc, yt)
self.distance = self.euclidean_distance( self.distance = (self.euclidean_distance(xc, xt, yc, yt) *
xc, xt, yc, yt) * self.pixel_to_metric_ratio() self.pixel_to_metric_ratio())
return self.distance return self.distance

257
temp.py
View File

@ -1,40 +1,61 @@
import warnings
import os
from tabulate import tabulate
warnings.filterwarnings("ignore",
category=UserWarning,
module="google.protobuf")
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
import argparse import argparse
import math import math
import cv2 import cv2
import mediapipe as mp from mediapipe.python.solutions import pose
import logging
class Landmarker: class Landmarker:
resized_height = 256
resized_width = 300
def __init__(self) -> None: def __init__(self) -> None:
args = self.parse_args() args = self.parse_args()
if args.front_image == None: if args.front_image is None:
raise Exception("front image needs to be passed") raise Exception("Front image needs to be passed")
if args.side_image == None: if args.side_image is None:
raise Exception("side image needs to be passed") raise Exception("Side image needs to be passed")
self.front_image = cv2.imread(args.front_image) self.front_image = cv2.imread(args.front_image)
self.side_image = cv2.imread(args.side_image) self.side_image = cv2.imread(args.side_image)
mp_pose = mp.solutions.pose self.front_image_resized = cv2.resize(
self.pose = mp_pose.Pose( self.front_image, (self.resized_height, self.resized_width))
self.side_image_resized = cv2.resize(
self.side_image, (self.resized_height, self.resized_width))
self.person_height = args.person_height
self.pixel_height = args.pixel_height
self.pose = pose.Pose(
static_image_mode=True, static_image_mode=True,
min_detection_confidence=args.pose_detection_confidence, min_detection_confidence=args.pose_detection_confidence,
min_tracking_confidence=args.pose_tracking_confidence, min_tracking_confidence=args.pose_tracking_confidence,
) )
self.resized_height = 256
self.resized_width = int(
self.front_image.shape[1] *
(self.resized_height / self.front_image.shape[0]))
self.front_image_resized = cv2.resize(
self.front_image, (self.resized_width, self.resized_height))
self.side_image_resized = cv2.resize(
self.side_image, (self.resized_width, self.resized_height))
self.landmarks_indices = [ self.landmarks_indices = [
11, 12, 13, 14, 15, 16, 23, 24, 25, 26, 27, 28 pose.PoseLandmark.LEFT_SHOULDER.value,
pose.PoseLandmark.RIGHT_SHOULDER.value,
pose.PoseLandmark.LEFT_ELBOW.value,
pose.PoseLandmark.RIGHT_ELBOW.value,
pose.PoseLandmark.LEFT_WRIST.value,
pose.PoseLandmark.RIGHT_WRIST.value,
pose.PoseLandmark.LEFT_HIP.value,
pose.PoseLandmark.RIGHT_HIP.value,
pose.PoseLandmark.LEFT_KNEE.value,
pose.PoseLandmark.RIGHT_KNEE.value,
pose.PoseLandmark.LEFT_ANKLE.value,
pose.PoseLandmark.RIGHT_ANKLE.value,
] ]
def parse_args(self): def parse_args(self):
@ -47,19 +68,52 @@ class Landmarker:
dest="side_image", dest="side_image",
type=str, type=str,
help="Side image") help="Side image")
parser.add_argument("--pose_detection_confidence", parser.add_argument(
deafult=0.5, "--pose_detection_confidence",
dest="Pose detection confidence", dest="pose_detection_confidence",
type=float,
help="Confidence score for pose detection")
parser.add_argument("--pose_tracking_confidence",
default=0.5, default=0.5,
dest="Pose detection tracking",
type=float, type=float,
help="Confidence score for pose tracking") help="Confidence score for pose detection",
)
parser.add_argument(
"--pose_tracking_confidence",
dest="pose_tracking_confidence",
default=0.5,
type=float,
help="Confidence score for pose tracking",
)
parser.add_argument(
"--person_height",
default=153,
dest="person_height",
type=int,
help="Person height",
)
parser.add_argument(
"--pixel_height",
dest="pixel_height",
type=int,
help="Pixel height of person",
)
return parser.parse_args() return parser.parse_args()
def run(self): def run(self):
logging.warning("Person's height: %s", self.person_height)
logging.warning("Person's pixel height: %s", self.pixel_height)
front_results, side_results = self.process_images()
self.get_center_top_point(front_results)
self.calculate_distance_for_landmarks(front_results)
self.output()
self.display_images()
self.pose.close()
def process_images(self):
front_results = self.pose.process( front_results = self.pose.process(
cv2.cvtColor(self.front_image_resized, cv2.COLOR_BGR2RGB)) cv2.cvtColor(self.front_image_resized, cv2.COLOR_BGR2RGB))
side_results = self.pose.process( side_results = self.pose.process(
@ -68,143 +122,116 @@ class Landmarker:
self.side_image_keypoints = self.side_image_resized.copy() self.side_image_keypoints = self.side_image_resized.copy()
self.front_image_keypoints = self.front_image_resized.copy() self.front_image_keypoints = self.front_image_resized.copy()
if front_results.pose_landmarks: if front_results.pose_landmarks: # type: ignore
self.draw_landmarks( self.draw_landmarks(
self.front_image_keypoints, self.front_image_keypoints,
front_results.pose_landmarks, front_results.pose_landmarks, # type: ignore
self.landmarks_indices, self.landmarks_indices,
) )
if side_results.pose_landmarks: if side_results.pose_landmarks: # type: ignore
self.draw_landmarks( self.draw_landmarks(
self.side_image_keypoints, self.side_image_keypoints,
side_results.pose_landmarks, side_results.pose_landmarks, # type: ignore
self.landmarks_indices, self.landmarks_indices,
) )
return front_results, side_results
self.get_center_top_point(front_results) def calculate_distance_for_landmarks(self, landmarks):
real_distance = 0
self.print_distance(front_results) if len(landmarks) > 1:
for i in range(0, len(landmarks) - 1):
self.display_images() _current = landmarks[self.landmarks_indices[i]]
_next = landmarks[self.landmarks_indices[i + 1]]
self.pose.close() pixel_distance = self.euclidean_distance(
_current.x, _current.y, _next.x, _next.y)
def calculate_distance(self, landmark1, landmark2): real_distance += pixel_distance * self.pixel_to_metric_ratio()
l1 = landmark1.x, landmark1.y logging.warning("Total real distance: %s", real_distance)
l1 = int(l1[0] * self.resized_width), int(l1[1] * self.resized_height)
x1, y1 = l1
l2 = landmark2.x, landmark2.y
l2 = int(l2[0] * self.resized_width), int(l2[1] * self.resized_height)
x2, y2 = l2
pixel_distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
real_distance = pixel_distance * self.pixel_to_metric_ratio()
return real_distance return real_distance
def pixel_to_metric_ratio(self): def pixel_to_metric_ratio(self):
height_person = 153 self.pixel_height = self.pixel_distance * 2
pixel_distance_height = 255 pixel_to_metric_ratio = self.person_height / self.pixel_height
pixel_to_metric_ratio = height_person / pixel_distance_height logging.warning("Pixel to metric ratio: %s", pixel_to_metric_ratio)
pixel_to_metric_ratio = round(pixel_to_metric_ratio)
return pixel_to_metric_ratio return pixel_to_metric_ratio
def draw_landmarks(self, image, landmarks, indices): def draw_landmarks(self, image, landmarks, indices):
for idx in indices: for idx in indices:
landmark = landmarks.landmark[idx] landmark = landmarks[idx]
h, w, _ = image.shape h, w, _ = image.shape
cx, cy = int(landmark.x * w), int(landmark.y * h) cx, cy = int(landmark.x * w), int(landmark.y * h)
cv2.circle(image, (cx, cy), 2, (255, 0, 0), -1) self.circle(image, cx, cy)
def print_distance(self, front_results): def circle(self, image, cx, cy):
if not front_results.pose_landmarks: return cv2.circle(image, (cx, cy), 2, (255, 0, 0), -1)
return
landmarks = front_results.pose_landmarks.landmark def output(self):
table = [["shoulder", 1], ["neck", 2]]
output = tabulate(table,
headers=["Measurement", "Value"],
tablefmt="plain")
print(output)
shoulder_left = landmarks[11] def euclidean_distance(self, x1, y1, x2, y2):
elbow_left = landmarks[13] distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
wrist_left = landmarks[15] return distance
hip_left = landmarks[23]
knee_left = landmarks[25]
ankle_left = landmarks[27]
distance_left_hand_up = self.calculate_distance( def destroy(self):
shoulder_left, elbow_left)
print("Distance between left shoulder and left elbow:",
distance_left_hand_up)
distance_left_hand_down = self.calculate_distance(
elbow_left, wrist_left)
print("Distance between left elbow and left wrist:",
distance_left_hand_down)
distance_left_leg_up = self.calculate_distance(hip_left, knee_left)
print("Distance between left hip and left knee:", distance_left_leg_up)
distance_left_leg_down = self.calculate_distance(knee_left, ankle_left)
print("Distance between left knee and left ankle:",
distance_left_leg_down)
def destroy():
cv2.destroyAllWindows() cv2.destroyAllWindows()
def display_images(self): def display_images(self):
cv2.imshow("front_image_keypoints", self.front_image_keypoints) cv2.imshow("front_image_keypoints", self.front_image_keypoints)
cv2.imshow("side_image_keypoints", self.side_image_keypoints) cv2.imshow("side_image_keypoints", self.side_image_keypoints)
cv2.imshow("edges", self.edges)
cv2.waitKey(0)
def get_center_top_point(self, front_results): def get_center_top_point(self, side_results):
gray_image = cv2.cvtColor(self.front_image_keypoints, gray_image = cv2.cvtColor(self.side_image_keypoints,
cv2.COLOR_BGR2GRAY) cv2.COLOR_BGR2GRAY)
blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0) blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
roi = blurred_image[0:int(self.resized_height / 2), :] roi = blurred_image[0:int(self.side_image_resized.shape[0] / 2), :]
edges = cv2.Canny(roi, 50, 150) self.edges = cv2.Canny(roi, 50, 150)
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, contours, _ = cv2.findContours(self.edges, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE) cv2.CHAIN_APPROX_SIMPLE)
xt, yt = None, None
self.topmost_point = None self.topmost_point = None
outermost_contours = [ if contours:
contours[i] for i in range(len(contours)) largest_contour = max(contours, key=cv2.contourArea)
if hierarchy[0][i][3] == -1
]
if outermost_contours:
largest_contour = max(outermost_contours, key=cv2.contourArea)
self.topmost_point = tuple( self.topmost_point = tuple(
largest_contour[largest_contour[:, :, 1].argmin()][0]) largest_contour[largest_contour[:, :, 1].argmin()][0])
# topmost_point = (int(topmost_point[0]*self.resized_width), int(topmost_point[1] * self.resized_height)) xt, yt = self.topmost_point
topmost_point = (self.topmost_point[0], self.topmost_point[1]) self.circle(self.side_image_keypoints, xt, yt)
cv2.circle(self.front_image_keypoints, topmost_point, 2,
(255, 0, 0), -1)
self.left_hip_idx = 23 logging.warning("xt: %s", xt)
self.right_hip_idx = 24 logging.warning("yt: %s", yt)
xc, yc = None, None
landmarks = side_results.pose_landmarks.landmark
self.center_point = None if side_results.pose_landmarks: # type: ignore
left_hip = landmarks[pose.PoseLandmark.LEFT_HIP.value]
if front_results.pose_landmarks: right_hip = landmarks[pose.PoseLandmark.RIGHT_HIP.value]
left_hip = front_results.pose_landmarks.landmark[self.left_hip_idx]
right_hip = front_results.pose_landmarks.landmark[
self.right_hip_idx]
center_point = ( center_point = (
(left_hip.x + right_hip.x) / 2, (left_hip.x + right_hip.x) / 2,
(left_hip.y + right_hip.y) / 2, (left_hip.y + right_hip.y) / 2,
) )
center_point = ( center_point = (
int(center_point[0] * self.resized_width), int(center_point[0] * self.side_image_resized.shape[1]),
int(center_point[1] * self.resized_height), int(center_point[1] * self.side_image_resized.shape[0]),
) )
cv2.circle(self.front_image_keypoints, center_point, 2,
(255, 0, 0), -1)
xc, yc = center_point xc, yc = center_point
xt, yt = topmost_point logging.warning("xc: %s", xc)
distance = math.sqrt((xc - xt)**2 + (yc - yt)**2) logging.warning("yc: %s", yc)
#return distance self.circle(self.side_image_keypoints, xc, yc)
return center_point
self.pixel_distance = self.euclidean_distance(xc, xt, yc, yt)
self.distance = self.pixel_distance * self.pixel_to_metric_ratio()
return self.distance
l = Landmarker() l = Landmarker()
try: try:
l.run() l.run()
except: except Exception as e:
pass print(f"Error: {e}")
finally: finally:
l.destroy() l.destroy()

38
trial.py Normal file
View File

@ -0,0 +1,38 @@
import cv2
import mediapipe as mp
def detect_points(image_path):
image = cv2.imread(image_path)
target_width = 256
target_height = int(image.shape[0] * target_width / image.shape[1])
image = cv2.resize(image, (target_width, target_height))
mp_pose = mp.solutions.pose #type: ignore
pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.5)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
if results.pose_landmarks:
for landmark in results.pose_landmarks.landmark:
cv2.circle(
image,
(int(landmark.x * image.shape[1]),
int(landmark.y * image.shape[0])),
5,
(0, 255, 0),
-1,
)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
image_path = "/home/aparna/projects/aubome/assets/aparna_side.jpg"
detect_points(image_path)