Improved risen hand detection and fixes

This commit is contained in:
charlesbvll 2021-04-14 18:00:50 +02:00
parent c71d34f749
commit 5e033588c8
5 changed files with 56 additions and 11 deletions

View File

@ -66,22 +66,51 @@ def social_interactions(idx, centers, angles, dds, stds=None, social_distance=Fa
return False
def is_raising_hand(keypoint):
def is_raising_hand(kp):
"""
Returns flag of alert if someone raises their hand
"""
x=0
y=1
nose = 0
l_ear = 3
l_shoulder = 5
l_elbow = 7
l_hand = 9
r_ear = 4
r_shoulder = 6
r_elbow = 8
r_hand = 10
if keypoint[1][l_hand] < keypoint[1][l_shoulder] and keypoint[1][r_hand] < keypoint[1][r_shoulder]:
head_width = kp[x][l_ear]- kp[x][r_ear]
head_top = (4/5) * (kp[y][nose] - head_width)
l_forearm = [kp[x][l_hand] - kp[x][l_elbow], kp[y][l_hand] - kp[y][l_elbow]]
l_arm = [kp[x][l_shoulder] - kp[x][l_elbow], kp[y][l_shoulder] - kp[y][l_elbow]]
r_forearm = [kp[x][r_hand] - kp[x][r_elbow], kp[y][r_hand] - kp[y][r_elbow]]
r_arm = [kp[x][r_shoulder] - kp[x][r_elbow], kp[y][r_shoulder] - kp[y][r_elbow]]
l_angle = (90/np.pi) * np.arccos(np.dot(l_forearm/np.linalg.norm(l_forearm), l_arm/np.linalg.norm(l_arm)))
r_angle = (90/np.pi) * np.arccos(np.dot(r_forearm/np.linalg.norm(r_forearm), r_arm/np.linalg.norm(r_arm)))
is_l_up = kp[y][l_hand] < kp[y][l_shoulder]
is_r_up = kp[y][r_hand] < kp[y][r_shoulder]
l_too_close = kp[x][l_hand] <= kp[x][l_shoulder] and kp[y][l_hand]>=head_top
r_too_close = kp[x][r_hand] >= kp[x][r_shoulder] and kp[y][r_hand]>=head_top
is_left_risen = is_l_up and l_angle >= 30 and not l_too_close
is_right_risen = is_r_up and r_angle >= 30 and not r_too_close
if is_left_risen and is_right_risen:
return 'both'
if keypoint[1][l_hand] < keypoint[1][l_shoulder]:
if is_left_risen:
return 'left'
if keypoint[1][r_hand] < keypoint[1][r_shoulder]:
if is_right_risen:
return 'right'
return 'none'

View File

@ -19,7 +19,7 @@ def cli():
predict_parser.add_argument('images', nargs='*', help='input images')
predict_parser.add_argument('--glob', help='glob expression for input images (for many images)')
predict_parser.add_argument('-o', '--output-directory', help='Output directory')
predict_parser.add_argument('--output_types', nargs='+', default=['json'],
predict_parser.add_argument('--output_types', nargs='+',
help='what to output: json keypoints skeleton for Pifpaf'
'json bird front or multi for MonStereo')
predict_parser.add_argument('--no_save', help='to show images', action='store_true')
@ -131,6 +131,8 @@ def main():
from .visuals.webcam import webcam
webcam(args)
else:
if args.output_types is None:
args.output_types = ['json']
from .predict import predict
predict(args)

View File

@ -103,7 +103,7 @@ class KeypointPainter(object):
linewidth = np.sqrt((x[9]-x[7])**2 + (y[9]-y[7])**2)
if ((connection[0] == 6 and connection[1] == 8) or (connection[0] == 8 and connection[1] == 10)) and raise_hand in ['right', 'both']:
c = 'yellow'
linewidth = np.sqrt((x[9]-x[7])**2 + (y[9]-y[7])**2)
linewidth = np.sqrt((x[10]-x[8])**2 + (y[10]-y[8])**2)
if self.color_connections:
c = matplotlib.cm.get_cmap('tab20')(ci / len(self.skeleton))
if np.all(v[connection] > self.dashed_threshold):
@ -153,7 +153,7 @@ class KeypointPainter(object):
ax.text(x1, y1, '{:.4f}'.format(score), fontsize=8, color=color)
@staticmethod
def _draw_text(ax, x, y, v, text, color):
def _draw_text(ax, x, y, v, text, color, fontsize=8):
if not np.any(v > 0):
return
@ -167,7 +167,7 @@ class KeypointPainter(object):
y1 -= 2.0
y2 += 2.0
ax.text(x1 + 2, y1 - 2, text, fontsize=8,
ax.text(x1 + 2, y1 - 2, text, fontsize=fontsize,
color='white', bbox={'facecolor': color, 'alpha': 0.5, 'linewidth': 0})
@staticmethod
@ -208,7 +208,7 @@ class KeypointPainter(object):
if score is not None:
z_str = str(score).split(sep='.')
text = z_str[0] + '.' + z_str[1][0]
self._draw_text(ax, x-2, y, v, text, color)
self._draw_text(ax, x[1:3], y[1:3]-5, v[1:3], text, color, fontsize=16)
if self.show_box:
score = scores[i] if scores is not None else None
self._draw_box(ax, x, y, v, color, score)

View File

@ -417,6 +417,7 @@ class Printer:
uv_max = [0., float(self.height)]
xyz_max = pixel_to_camera(uv_max, self.kk, self.z_max)
x_max = abs(xyz_max[0]) # shortcut to avoid oval circles in case of different kk
x_max=6
corr = round(float(x_max / 3))
ax.plot([0, x_max], [0, self.z_max], 'k--')
ax.plot([0, -x_max], [0, self.z_max], 'k--')

View File

@ -13,7 +13,10 @@ import logging
import torch
import matplotlib.pyplot as plt
from PIL import Image
import cv2
try:
import cv2
except ImportError:
cv2 = None
from openpifpaf import decoder, network, visualizer, show, logger
import openpifpaf.datasets as datasets
@ -33,6 +36,15 @@ def factory_from_args(args):
args.checkpoint = dic_models['keypoints']
logger.configure(args, LOG) # logger first
if args.output_types is None:
args.output_types = ['multi']
assert 'bird' not in args.output_types
if 'json' not in args.output_types:
assert len(args.output_types) is 1
else:
assert len(args.output_types) < 3
# Devices
args.device = torch.device('cpu')
@ -67,6 +79,7 @@ def factory_from_args(args):
def webcam(args):
assert args.mode in ('mono')
args, dic_models = factory_from_args(args)
# Load Models
@ -175,7 +188,7 @@ class Visualizer:
axes[1].lines = [axes[1].lines[0], axes[1].lines[1]]
axes[1].texts = []
if dic_out:
if dic_out and dic_out['dds_pred']:
printer._process_results(dic_out)
printer.draw(figures, axes, image, dic_out, pifpaf_outs['left'])
mypause(0.01)