Improved risen hand detection and fixes
This commit is contained in:
parent
c71d34f749
commit
5e033588c8
@ -66,22 +66,51 @@ def social_interactions(idx, centers, angles, dds, stds=None, social_distance=Fa
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_raising_hand(keypoint):
|
def is_raising_hand(kp):
|
||||||
"""
|
"""
|
||||||
Returns flag of alert if someone raises their hand
|
Returns flag of alert if someone raises their hand
|
||||||
"""
|
"""
|
||||||
|
x=0
|
||||||
|
y=1
|
||||||
|
|
||||||
|
nose = 0
|
||||||
|
l_ear = 3
|
||||||
l_shoulder = 5
|
l_shoulder = 5
|
||||||
|
l_elbow = 7
|
||||||
l_hand = 9
|
l_hand = 9
|
||||||
|
r_ear = 4
|
||||||
r_shoulder = 6
|
r_shoulder = 6
|
||||||
|
r_elbow = 8
|
||||||
r_hand = 10
|
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'
|
return 'both'
|
||||||
|
|
||||||
if keypoint[1][l_hand] < keypoint[1][l_shoulder]:
|
if is_left_risen:
|
||||||
return 'left'
|
return 'left'
|
||||||
|
|
||||||
if keypoint[1][r_hand] < keypoint[1][r_shoulder]:
|
if is_right_risen:
|
||||||
return 'right'
|
return 'right'
|
||||||
|
|
||||||
return 'none'
|
return 'none'
|
||||||
|
|||||||
@ -19,7 +19,7 @@ def cli():
|
|||||||
predict_parser.add_argument('images', nargs='*', help='input images')
|
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('--glob', help='glob expression for input images (for many images)')
|
||||||
predict_parser.add_argument('-o', '--output-directory', help='Output directory')
|
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'
|
help='what to output: json keypoints skeleton for Pifpaf'
|
||||||
'json bird front or multi for MonStereo')
|
'json bird front or multi for MonStereo')
|
||||||
predict_parser.add_argument('--no_save', help='to show images', action='store_true')
|
predict_parser.add_argument('--no_save', help='to show images', action='store_true')
|
||||||
@ -131,6 +131,8 @@ def main():
|
|||||||
from .visuals.webcam import webcam
|
from .visuals.webcam import webcam
|
||||||
webcam(args)
|
webcam(args)
|
||||||
else:
|
else:
|
||||||
|
if args.output_types is None:
|
||||||
|
args.output_types = ['json']
|
||||||
from .predict import predict
|
from .predict import predict
|
||||||
predict(args)
|
predict(args)
|
||||||
|
|
||||||
|
|||||||
@ -103,7 +103,7 @@ class KeypointPainter(object):
|
|||||||
linewidth = np.sqrt((x[9]-x[7])**2 + (y[9]-y[7])**2)
|
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']:
|
if ((connection[0] == 6 and connection[1] == 8) or (connection[0] == 8 and connection[1] == 10)) and raise_hand in ['right', 'both']:
|
||||||
c = 'yellow'
|
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:
|
if self.color_connections:
|
||||||
c = matplotlib.cm.get_cmap('tab20')(ci / len(self.skeleton))
|
c = matplotlib.cm.get_cmap('tab20')(ci / len(self.skeleton))
|
||||||
if np.all(v[connection] > self.dashed_threshold):
|
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)
|
ax.text(x1, y1, '{:.4f}'.format(score), fontsize=8, color=color)
|
||||||
|
|
||||||
@staticmethod
|
@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):
|
if not np.any(v > 0):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ class KeypointPainter(object):
|
|||||||
y1 -= 2.0
|
y1 -= 2.0
|
||||||
y2 += 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})
|
color='white', bbox={'facecolor': color, 'alpha': 0.5, 'linewidth': 0})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -208,7 +208,7 @@ class KeypointPainter(object):
|
|||||||
if score is not None:
|
if score is not None:
|
||||||
z_str = str(score).split(sep='.')
|
z_str = str(score).split(sep='.')
|
||||||
text = z_str[0] + '.' + z_str[1][0]
|
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:
|
if self.show_box:
|
||||||
score = scores[i] if scores is not None else None
|
score = scores[i] if scores is not None else None
|
||||||
self._draw_box(ax, x, y, v, color, score)
|
self._draw_box(ax, x, y, v, color, score)
|
||||||
|
|||||||
@ -417,6 +417,7 @@ class Printer:
|
|||||||
uv_max = [0., float(self.height)]
|
uv_max = [0., float(self.height)]
|
||||||
xyz_max = pixel_to_camera(uv_max, self.kk, self.z_max)
|
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 = abs(xyz_max[0]) # shortcut to avoid oval circles in case of different kk
|
||||||
|
x_max=6
|
||||||
corr = round(float(x_max / 3))
|
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--')
|
||||||
ax.plot([0, -x_max], [0, self.z_max], 'k--')
|
ax.plot([0, -x_max], [0, self.z_max], 'k--')
|
||||||
|
|||||||
@ -13,7 +13,10 @@ import logging
|
|||||||
import torch
|
import torch
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import cv2
|
try:
|
||||||
|
import cv2
|
||||||
|
except ImportError:
|
||||||
|
cv2 = None
|
||||||
|
|
||||||
from openpifpaf import decoder, network, visualizer, show, logger
|
from openpifpaf import decoder, network, visualizer, show, logger
|
||||||
import openpifpaf.datasets as datasets
|
import openpifpaf.datasets as datasets
|
||||||
@ -34,6 +37,15 @@ def factory_from_args(args):
|
|||||||
|
|
||||||
logger.configure(args, LOG) # logger first
|
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
|
# Devices
|
||||||
args.device = torch.device('cpu')
|
args.device = torch.device('cpu')
|
||||||
args.pin_memory = False
|
args.pin_memory = False
|
||||||
@ -67,6 +79,7 @@ def factory_from_args(args):
|
|||||||
def webcam(args):
|
def webcam(args):
|
||||||
|
|
||||||
assert args.mode in ('mono')
|
assert args.mode in ('mono')
|
||||||
|
|
||||||
args, dic_models = factory_from_args(args)
|
args, dic_models = factory_from_args(args)
|
||||||
|
|
||||||
# Load Models
|
# Load Models
|
||||||
@ -175,7 +188,7 @@ class Visualizer:
|
|||||||
axes[1].lines = [axes[1].lines[0], axes[1].lines[1]]
|
axes[1].lines = [axes[1].lines[0], axes[1].lines[1]]
|
||||||
axes[1].texts = []
|
axes[1].texts = []
|
||||||
|
|
||||||
if dic_out:
|
if dic_out and dic_out['dds_pred']:
|
||||||
printer._process_results(dic_out)
|
printer._process_results(dic_out)
|
||||||
printer.draw(figures, axes, image, dic_out, pifpaf_outs['left'])
|
printer.draw(figures, axes, image, dic_out, pifpaf_outs['left'])
|
||||||
mypause(0.01)
|
mypause(0.01)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user