change folders
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 3.7 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.4 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -1,16 +0,0 @@
|
|||||||
import openpifpaf
|
|
||||||
|
|
||||||
from . import karusel_kp
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
openpifpaf.DATAMODULES['karusel'] = karusel_kp.karusel_Kp
|
|
||||||
openpifpaf.CHECKPOINT_URLS['shufflenetv2k16-apollo-24'] = \
|
|
||||||
"http://github.com/DuncanZauss/openpifpaf_assets/releases/" \
|
|
||||||
"download/v0.1.0/shufflenetv2k16-201113-135121-apollo.pkl.epoch290"
|
|
||||||
openpifpaf.CHECKPOINT_URLS['shufflenetv2k16-apollo-66'] = \
|
|
||||||
"http://github.com/DuncanZauss/openpifpaf_assets/releases/" \
|
|
||||||
"download/v0.1.0/sk16_apollo_66kp.pkl"
|
|
||||||
openpifpaf.CHECKPOINT_URLS['shufflenetv2k30-apollo-66'] = \
|
|
||||||
"http://github.com/DuncanZauss/openpifpaf_assets/releases/" \
|
|
||||||
"download/v0.1.0/sk30_apollo_66kp.pkl"
|
|
||||||
@@ -1,267 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
try:
|
|
||||||
import matplotlib.cm as mplcm
|
|
||||||
from matplotlib.animation import FuncAnimation
|
|
||||||
from mpl_toolkits.mplot3d import Axes3D
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
import openpifpaf
|
|
||||||
|
|
||||||
CAR_KEYPOINTS_24 = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12',
|
|
||||||
'13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']
|
|
||||||
|
|
||||||
CAR_SKELETON_24 = [
|
|
||||||
[1, 2],[2, 3],[3, 4],[4, 5],[5, 6],[6, 7],[7, 8],[8, 9],[9, 10],[10, 11],
|
|
||||||
[11, 12],[12, 13],[13, 14],[14, 15],[15, 16],[16, 17],[17, 18],[18, 19],[19, 20],
|
|
||||||
[20, 21],[21, 22],[22, 23],[23, 24],[24, 1],[24, 3],[1, 5]
|
|
||||||
]
|
|
||||||
|
|
||||||
CAR_CATEGORIES_24 = ['karusel']
|
|
||||||
|
|
||||||
|
|
||||||
CAR_SCORE_WEIGHTS_24 = [5,5,5,0.5,2,2,5,1,1,1,1,4,3,2,3,3,3,1,5,5,2,4,0.5,2]
|
|
||||||
|
|
||||||
CAR_SIGMAS_24 = [0.05] * len(CAR_KEYPOINTS_24)
|
|
||||||
|
|
||||||
CAR_POSE_24 = np.array([[ 129., -137., 0.],
|
|
||||||
[ -41., 33., 0.],
|
|
||||||
[ -65., 46., 0.],
|
|
||||||
[ 22., -134., 0.],
|
|
||||||
[ 70., -253., 0.],
|
|
||||||
[ 69., -329., 0.],
|
|
||||||
[ -37., -224., 0.],
|
|
||||||
[ -88., -199., 0.],
|
|
||||||
[-143., -171., 0.],
|
|
||||||
[-173., -119., 0.],
|
|
||||||
[-219., -30., 0.],
|
|
||||||
[-307., -26., 0.],
|
|
||||||
[-207., 123., 0.],
|
|
||||||
[-138., 258., 0.],
|
|
||||||
[ -43., 240., 0.],
|
|
||||||
[ 10., 242., 0.],
|
|
||||||
[ 62., 229., 0.],
|
|
||||||
[ 146., 174., 0.],
|
|
||||||
[ 213., 138., 0.],
|
|
||||||
[ 230., 59., 0.],
|
|
||||||
[ 302., -11., 0.],
|
|
||||||
[ 288., -93., 0.],
|
|
||||||
[ 172., -65., 0.],
|
|
||||||
[ 103., -14., 0.]])
|
|
||||||
|
|
||||||
HFLIP_24 = {
|
|
||||||
'1': '1',
|
|
||||||
'2': '2',
|
|
||||||
'3': '3',
|
|
||||||
'4': '4',
|
|
||||||
'5': '5',
|
|
||||||
'6': '6',
|
|
||||||
'7': '7',
|
|
||||||
'8': '8',
|
|
||||||
'9': '9',
|
|
||||||
'10': '10',
|
|
||||||
'11': '11',
|
|
||||||
'12': '12',
|
|
||||||
'13': '13',
|
|
||||||
'14': '14',
|
|
||||||
'15': '15',
|
|
||||||
'16': '16',
|
|
||||||
'17': '17',
|
|
||||||
'18': '18',
|
|
||||||
'19': '19',
|
|
||||||
'20': '20',
|
|
||||||
'21': '21',
|
|
||||||
'22': '22',
|
|
||||||
'23': '23',
|
|
||||||
'24': '24'
|
|
||||||
}
|
|
||||||
|
|
||||||
training_weights_local_centrality = [
|
|
||||||
0.890968488270775,
|
|
||||||
0.716506138617812,
|
|
||||||
1.05674590410869,
|
|
||||||
0.764774195768455,
|
|
||||||
0.637682585483328,
|
|
||||||
0.686680807728366,
|
|
||||||
0.955422595797394,
|
|
||||||
0.936714585642375,
|
|
||||||
1.34823795445326,
|
|
||||||
1.38308992581967,
|
|
||||||
1.32689945125819,
|
|
||||||
1.38838655605483,
|
|
||||||
1.18980184904613,
|
|
||||||
1.02584355494795,
|
|
||||||
0.90969156732068,
|
|
||||||
1.24732068576104,
|
|
||||||
1.11338768064342,
|
|
||||||
0.933815217550391,
|
|
||||||
0.852297518872114,
|
|
||||||
1.04167641424727,
|
|
||||||
1.01668968075247,
|
|
||||||
1.34625964088011,
|
|
||||||
0.911796331039028,
|
|
||||||
0.866206536337413,
|
|
||||||
1.55957820407853,
|
|
||||||
0.730844382675724,
|
|
||||||
0.651138644197359,
|
|
||||||
0.758018559633786,
|
|
||||||
1.31842501396691,
|
|
||||||
1.32186116654782,
|
|
||||||
0.744347016851606,
|
|
||||||
0.636390683664723,
|
|
||||||
0.715244950821949,
|
|
||||||
1.63122349407032,
|
|
||||||
0.849835699185461,
|
|
||||||
0.910488007220499,
|
|
||||||
1.44244151650561,
|
|
||||||
1.14150437331681,
|
|
||||||
1.19808610191343,
|
|
||||||
0.960186788642886,
|
|
||||||
1.05023623286937,
|
|
||||||
1.19761709710598,
|
|
||||||
1.3872216313401,
|
|
||||||
1.01256700741214,
|
|
||||||
1.1167909667759,
|
|
||||||
1.27893496336199,
|
|
||||||
1.54475684725655,
|
|
||||||
1.40343733870633,
|
|
||||||
1.45552060866114,
|
|
||||||
1.47264222155031,
|
|
||||||
0.970060423999993,
|
|
||||||
0.944450314768933,
|
|
||||||
0.623987071240172,
|
|
||||||
0.5745237907704,
|
|
||||||
0.66890646050993,
|
|
||||||
0.978411632994504,
|
|
||||||
0.587396395188292,
|
|
||||||
0.76307999741129,
|
|
||||||
0.609793563449648,
|
|
||||||
0.67983566494545,
|
|
||||||
0.685883538168462,
|
|
||||||
0.753587600664775,
|
|
||||||
0.770335133588157,
|
|
||||||
0.764713638033368,
|
|
||||||
0.792364155965385,
|
|
||||||
0.796435233566833
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def get_constants(num_kps):
|
|
||||||
if num_kps == 24:
|
|
||||||
CAR_POSE_24[:, 2] = 2.0
|
|
||||||
return [CAR_KEYPOINTS_24, CAR_SKELETON_24, HFLIP_24, CAR_SIGMAS_24,
|
|
||||||
CAR_POSE_24, CAR_CATEGORIES_24, CAR_SCORE_WEIGHTS_24]
|
|
||||||
if num_kps == 66:
|
|
||||||
CAR_POSE_66[:, 2] = 2.0
|
|
||||||
return [CAR_KEYPOINTS_66, CAR_SKELETON_66, HFLIP_66, CAR_SIGMAS_66,
|
|
||||||
CAR_POSE_66, CAR_CATEGORIES_66, CAR_SCORE_WEIGHTS_66]
|
|
||||||
# using no if-elif-else construction due to pylint no-else-return error
|
|
||||||
raise Exception("Only poses with 24 or 66 keypoints are available.")
|
|
||||||
|
|
||||||
|
|
||||||
def draw_ann(ann, *, keypoint_painter, filename=None, margin=0.5, aspect=None, **kwargs):
|
|
||||||
from openpifpaf import show # pylint: disable=import-outside-toplevel
|
|
||||||
|
|
||||||
bbox = ann.bbox()
|
|
||||||
xlim = bbox[0] - margin, bbox[0] + bbox[2] + margin
|
|
||||||
ylim = bbox[1] - margin, bbox[1] + bbox[3] + margin
|
|
||||||
if aspect == 'equal':
|
|
||||||
fig_w = 5.0
|
|
||||||
else:
|
|
||||||
fig_w = 5.0 / (ylim[1] - ylim[0]) * (xlim[1] - xlim[0])
|
|
||||||
|
|
||||||
with show.canvas(filename, figsize=(fig_w, 5), nomargin=True, **kwargs) as ax:
|
|
||||||
ax.set_axis_off()
|
|
||||||
ax.set_xlim(*xlim)
|
|
||||||
ax.set_ylim(*ylim)
|
|
||||||
|
|
||||||
if aspect is not None:
|
|
||||||
ax.set_aspect(aspect)
|
|
||||||
|
|
||||||
keypoint_painter.annotation(ax, ann)
|
|
||||||
|
|
||||||
|
|
||||||
def draw_skeletons(pose, sigmas, skel, kps, scr_weights):
|
|
||||||
from openpifpaf.annotation import Annotation # pylint: disable=import-outside-toplevel
|
|
||||||
from openpifpaf import show # pylint: disable=import-outside-toplevel
|
|
||||||
|
|
||||||
scale = np.sqrt(
|
|
||||||
(np.max(pose[:, 0]) - np.min(pose[:, 0]))
|
|
||||||
* (np.max(pose[:, 1]) - np.min(pose[:, 1]))
|
|
||||||
)
|
|
||||||
|
|
||||||
show.KeypointPainter.show_joint_scales = True
|
|
||||||
keypoint_painter = show.KeypointPainter()
|
|
||||||
ann = Annotation(keypoints=kps, skeleton=skel, score_weights=scr_weights)
|
|
||||||
ann.set(pose, np.array(sigmas) * scale)
|
|
||||||
os.makedirs('docs', exist_ok=True)
|
|
||||||
draw_ann(ann, filename='docs/skeleton_car.png', keypoint_painter=keypoint_painter)
|
|
||||||
|
|
||||||
|
|
||||||
def plot3d_red(ax_2D, p3d, skeleton):
|
|
||||||
skeleton = [(bone[0] - 1, bone[1] - 1) for bone in skeleton]
|
|
||||||
|
|
||||||
rot_p90_x = np.array([[1, 0, 0], [0, 0, 1], [0, 1, 0]])
|
|
||||||
p3d = p3d @ rot_p90_x
|
|
||||||
|
|
||||||
fig = ax_2D.get_figure()
|
|
||||||
ax = Axes3D(fig, auto_add_to_figure=False)
|
|
||||||
fig.add_axes(ax)
|
|
||||||
ax.set_axis_off()
|
|
||||||
ax_2D.set_axis_off()
|
|
||||||
|
|
||||||
ax.view_init(azim=-90, elev=20)
|
|
||||||
ax.set_xlabel('X')
|
|
||||||
ax.set_ylabel('Y')
|
|
||||||
ax.set_zlabel('Z')
|
|
||||||
max_range = np.array([p3d[:, 0].max() - p3d[:, 0].min(),
|
|
||||||
p3d[:, 1].max() - p3d[:, 1].min(),
|
|
||||||
p3d[:, 2].max() - p3d[:, 2].min()]).max() / 2.0
|
|
||||||
mid_x = (p3d[:, 0].max() + p3d[:, 0].min()) * 0.5
|
|
||||||
mid_y = (p3d[:, 1].max() + p3d[:, 1].min()) * 0.5
|
|
||||||
mid_z = (p3d[:, 2].max() + p3d[:, 2].min()) * 0.5
|
|
||||||
|
|
||||||
ax.set_xlim(mid_x - max_range, mid_x + max_range)
|
|
||||||
ax.set_ylim(mid_y - max_range, mid_y + max_range)
|
|
||||||
ax.set_zlim(mid_z - max_range, mid_z + max_range) # pylint: disable=no-member
|
|
||||||
|
|
||||||
for ci, bone in enumerate(skeleton):
|
|
||||||
c = mplcm.get_cmap('tab20')((ci % 20 + 0.05) / 20) # Same coloring as Pifpaf preds
|
|
||||||
ax.plot(p3d[bone, 0], p3d[bone, 1], p3d[bone, 2], color=c)
|
|
||||||
|
|
||||||
def animate(i):
|
|
||||||
ax.view_init(elev=10., azim=i)
|
|
||||||
return fig
|
|
||||||
|
|
||||||
return FuncAnimation(fig, animate, frames=360, interval=100)
|
|
||||||
|
|
||||||
|
|
||||||
def print_associations():
|
|
||||||
print("\nAssociations of the car skeleton with 24 keypoints")
|
|
||||||
for j1, j2 in CAR_SKELETON_24:
|
|
||||||
print(CAR_KEYPOINTS_24[j1 - 1], '-', CAR_KEYPOINTS_24[j2 - 1])
|
|
||||||
print("\nAssociations of the car skeleton with 66 keypoints")
|
|
||||||
for j1, j2 in CAR_SKELETON_66:
|
|
||||||
print(CAR_KEYPOINTS_66[j1 - 1], '-', CAR_KEYPOINTS_66[j2 - 1])
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# print_associations()
|
|
||||||
# =============================================================================
|
|
||||||
# draw_skeletons(CAR_POSE_24, sigmas = CAR_SIGMAS_24, skel = CAR_SKELETON_24,
|
|
||||||
# kps = CAR_KEYPOINTS_24, scr_weights = CAR_SCORE_WEIGHTS_24)
|
|
||||||
# draw_skeletons(CAR_POSE_66, sigmas = CAR_SIGMAS_66, skel = CAR_SKELETON_66,
|
|
||||||
# kps = CAR_KEYPOINTS_66, scr_weights = CAR_SCORE_WEIGHTS_66)
|
|
||||||
# =============================================================================
|
|
||||||
# with openpifpaf.show.Canvas.blank(nomargin=True) as ax_2D:
|
|
||||||
# anim_66 = plot3d_red(ax_2D, CAR_POSE_66, CAR_SKELETON_66)
|
|
||||||
# anim_66.save('./CAR_66_Pose.gif', fps=30)
|
|
||||||
with openpifpaf.show.Canvas.blank(nomargin=True) as ax_2D:
|
|
||||||
anim_24 = plot3d_red(ax_2D, CAR_POSE_24, CAR_SKELETON_24)
|
|
||||||
anim_24.save('./CAR_24_Pose.gif', fps=30)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
"""
|
|
||||||
Interface for custom data.
|
|
||||||
|
|
||||||
This module handles datasets and is the class that you need to inherit from for your custom dataset.
|
|
||||||
This class gives you all the handles so that you can train with a new –dataset=mydataset.
|
|
||||||
The particular configuration of keypoints and skeleton is specified in the headmeta instances
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import torch
|
|
||||||
import numpy as np
|
|
||||||
try:
|
|
||||||
from pycocotools.coco import COCO
|
|
||||||
except ImportError:
|
|
||||||
COCO = None
|
|
||||||
|
|
||||||
from openpifpaf.datasets import DataModule
|
|
||||||
from openpifpaf import encoder, headmeta, metric, transforms
|
|
||||||
from openpifpaf.datasets import collate_images_anns_meta, collate_images_targets_meta
|
|
||||||
from openpifpaf.plugins.coco import CocoDataset as CocoLoader
|
|
||||||
|
|
||||||
from .constants import get_constants, training_weights_local_centrality
|
|
||||||
from .metrics import MeanPixelError
|
|
||||||
|
|
||||||
|
|
||||||
class karusel_Kp(DataModule):
|
|
||||||
"""
|
|
||||||
DataModule for the karusel Dataset.
|
|
||||||
"""
|
|
||||||
|
|
||||||
train_annotations = 'Karusel_dataset-COCO/annotations/train.json'
|
|
||||||
val_annotations = 'Karusel_dataset-COCO/annotations/val.json'
|
|
||||||
eval_annotations = val_annotations
|
|
||||||
train_image_dir = 'Karusel_dataset-COCO/images/train/'
|
|
||||||
val_image_dir = 'Karusel_dataset-COCO/images/val/'
|
|
||||||
eval_image_dir = val_image_dir
|
|
||||||
|
|
||||||
n_images = None
|
|
||||||
square_edge = 513
|
|
||||||
extended_scale = False
|
|
||||||
orientation_invariant = 0.0
|
|
||||||
blur = 0.0
|
|
||||||
augmentation = True
|
|
||||||
rescale_images = 1.0
|
|
||||||
upsample_stride = 1
|
|
||||||
min_kp_anns = 1
|
|
||||||
b_min = 1 # 1 pixel
|
|
||||||
|
|
||||||
eval_annotation_filter = True
|
|
||||||
eval_long_edge = 0 # set to zero to deactivate rescaling
|
|
||||||
eval_orientation_invariant = 0.0
|
|
||||||
eval_extended_scale = False
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
if self.weights is not None:
|
|
||||||
caf_weights = []
|
|
||||||
for bone in self.CAR_SKELETON:
|
|
||||||
caf_weights.append(max(self.weights[bone[0] - 1],
|
|
||||||
self.weights[bone[1] - 1]))
|
|
||||||
w_np = np.array(caf_weights)
|
|
||||||
caf_weights = list(w_np / np.sum(w_np) * len(caf_weights))
|
|
||||||
else:
|
|
||||||
caf_weights = None
|
|
||||||
cif = headmeta.Cif('cif', 'apollo',
|
|
||||||
keypoints=self.CAR_KEYPOINTS,
|
|
||||||
sigmas=self.CAR_SIGMAS,
|
|
||||||
pose=self.CAR_POSE,
|
|
||||||
draw_skeleton=self.CAR_SKELETON,
|
|
||||||
score_weights=self.CAR_SCORE_WEIGHTS,
|
|
||||||
training_weights=self.weights)
|
|
||||||
caf = headmeta.Caf('caf', 'apollo',
|
|
||||||
keypoints=self.CAR_KEYPOINTS,
|
|
||||||
sigmas=self.CAR_SIGMAS,
|
|
||||||
pose=self.CAR_POSE,
|
|
||||||
skeleton=self.CAR_SKELETON,
|
|
||||||
training_weights=caf_weights)
|
|
||||||
|
|
||||||
cif.upsample_stride = self.upsample_stride
|
|
||||||
caf.upsample_stride = self.upsample_stride
|
|
||||||
self.head_metas = [cif, caf]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def cli(cls, parser: argparse.ArgumentParser):
|
|
||||||
group = parser.add_argument_group('data module Apollo')
|
|
||||||
|
|
||||||
group.add_argument('--karusel-train-annotations',
|
|
||||||
default=cls.train_annotations)
|
|
||||||
group.add_argument('--karusel-val-annotations',
|
|
||||||
default=cls.val_annotations)
|
|
||||||
group.add_argument('--karusel-train-image-dir',
|
|
||||||
default=cls.train_image_dir)
|
|
||||||
group.add_argument('--karusel-val-image-dir',
|
|
||||||
default=cls.val_image_dir)
|
|
||||||
|
|
||||||
group.add_argument('--karusel-square-edge',
|
|
||||||
default=cls.square_edge, type=int,
|
|
||||||
help='square edge of input images')
|
|
||||||
assert not cls.extended_scale
|
|
||||||
group.add_argument('--karusel-extended-scale',
|
|
||||||
default=False, action='store_true',
|
|
||||||
help='augment with an extended scale range')
|
|
||||||
group.add_argument('--karusel-orientation-invariant',
|
|
||||||
default=cls.orientation_invariant, type=float,
|
|
||||||
help='augment with random orientations')
|
|
||||||
group.add_argument('--karusel-blur',
|
|
||||||
default=cls.blur, type=float,
|
|
||||||
help='augment with blur')
|
|
||||||
assert cls.augmentation
|
|
||||||
group.add_argument('--karusel-no-augmentation',
|
|
||||||
dest='karusel_augmentation',
|
|
||||||
default=True, action='store_false',
|
|
||||||
help='do not apply data augmentation')
|
|
||||||
group.add_argument('--karusel-rescale-images',
|
|
||||||
default=cls.rescale_images, type=float,
|
|
||||||
help='overall rescale factor for images')
|
|
||||||
group.add_argument('--karusel-upsample',
|
|
||||||
default=cls.upsample_stride, type=int,
|
|
||||||
help='head upsample stride')
|
|
||||||
group.add_argument('--karusel-min-kp-anns',
|
|
||||||
default=cls.min_kp_anns, type=int,
|
|
||||||
help='filter images with fewer keypoint annotations')
|
|
||||||
group.add_argument('--karusel-bmin',
|
|
||||||
default=cls.b_min, type=int,
|
|
||||||
help='b minimum in pixels')
|
|
||||||
group.add_argument('--karusel-apply-local-centrality-weights',
|
|
||||||
dest='karusel_apply_local_centrality',
|
|
||||||
default=False, action='store_true',
|
|
||||||
help='Weigh the CIF and CAF head during training.')
|
|
||||||
|
|
||||||
# evaluation
|
|
||||||
assert cls.eval_annotation_filter
|
|
||||||
group.add_argument('--karusel-no-eval-annotation-filter',
|
|
||||||
dest='karusel_eval_annotation_filter',
|
|
||||||
default=True, action='store_false')
|
|
||||||
group.add_argument('--karusel-eval-long-edge', default=cls.eval_long_edge, type=int,
|
|
||||||
help='set to zero to deactivate rescaling')
|
|
||||||
assert not cls.eval_extended_scale
|
|
||||||
group.add_argument('--karusel-eval-extended-scale', default=False, action='store_true')
|
|
||||||
group.add_argument('--karusel-eval-orientation-invariant',
|
|
||||||
default=cls.eval_orientation_invariant, type=float)
|
|
||||||
group.add_argument('--karusel-use-24-kps', default=False, action='store_true',
|
|
||||||
help=('The ApolloCar3D dataset can '
|
|
||||||
'be trained with 24 or 66 kps. If you want to train a model '
|
|
||||||
'with 24 kps activate this flag. Change the annotations '
|
|
||||||
'path to the json files with 24 kps.'))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def configure(cls, args: argparse.Namespace):
|
|
||||||
# extract global information
|
|
||||||
cls.debug = args.debug
|
|
||||||
cls.pin_memory = args.pin_memory
|
|
||||||
|
|
||||||
# Apollo specific
|
|
||||||
cls.train_annotations = args.karusel_train_annotations
|
|
||||||
cls.val_annotations = args.karusel_val_annotations
|
|
||||||
cls.eval_annotations = cls.val_annotations
|
|
||||||
cls.train_image_dir = args.karusel_train_image_dir
|
|
||||||
cls.val_image_dir = args.karusel_val_image_dir
|
|
||||||
cls.eval_image_dir = cls.val_image_dir
|
|
||||||
|
|
||||||
cls.square_edge = args.karusel_square_edge
|
|
||||||
cls.extended_scale = args.karusel_extended_scale
|
|
||||||
cls.orientation_invariant = args.karusel_orientation_invariant
|
|
||||||
cls.blur = args.karusel_blur
|
|
||||||
cls.augmentation = args.karusel_augmentation # loaded by the dest name
|
|
||||||
cls.rescale_images = args.karusel_rescale_images
|
|
||||||
cls.upsample_stride = args.karusel_upsample
|
|
||||||
cls.min_kp_anns = args.karusel_min_kp_anns
|
|
||||||
cls.b_min = args.karusel_bmin
|
|
||||||
if args.karusel_use_24_kps:
|
|
||||||
(cls.CAR_KEYPOINTS, cls.CAR_SKELETON, cls.HFLIP, cls.CAR_SIGMAS, cls.CAR_POSE,
|
|
||||||
cls.CAR_CATEGORIES, cls.CAR_SCORE_WEIGHTS) = get_constants(24)
|
|
||||||
else:
|
|
||||||
(cls.CAR_KEYPOINTS, cls.CAR_SKELETON, cls.HFLIP, cls.CAR_SIGMAS, cls.CAR_POSE,
|
|
||||||
cls.CAR_CATEGORIES, cls.CAR_SCORE_WEIGHTS) = get_constants(66)
|
|
||||||
# evaluation
|
|
||||||
cls.eval_annotation_filter = args.karusel_eval_annotation_filter
|
|
||||||
cls.eval_long_edge = args.karusel_eval_long_edge
|
|
||||||
cls.eval_orientation_invariant = args.karusel_eval_orientation_invariant
|
|
||||||
cls.eval_extended_scale = args.karusel_eval_extended_scale
|
|
||||||
if args.karusel_apply_local_centrality:
|
|
||||||
if args.karusel_use_24_kps:
|
|
||||||
raise Exception("Applying local centrality weights only works with 66 kps.")
|
|
||||||
cls.weights = training_weights_local_centrality
|
|
||||||
else:
|
|
||||||
cls.weights = None
|
|
||||||
|
|
||||||
def _preprocess(self):
|
|
||||||
encoders = (encoder.Cif(self.head_metas[0], bmin=self.b_min),
|
|
||||||
encoder.Caf(self.head_metas[1], bmin=self.b_min))
|
|
||||||
|
|
||||||
if not self.augmentation:
|
|
||||||
return transforms.Compose([
|
|
||||||
transforms.NormalizeAnnotations(),
|
|
||||||
transforms.RescaleAbsolute(self.square_edge),
|
|
||||||
transforms.CenterPad(self.square_edge),
|
|
||||||
transforms.EVAL_TRANSFORM,
|
|
||||||
transforms.Encoders(encoders),
|
|
||||||
])
|
|
||||||
|
|
||||||
if self.extended_scale:
|
|
||||||
rescale_t = transforms.RescaleRelative(
|
|
||||||
scale_range=(0.2 * self.rescale_images,
|
|
||||||
2.0 * self.rescale_images),
|
|
||||||
power_law=True, stretch_range=(0.75, 1.33))
|
|
||||||
else:
|
|
||||||
rescale_t = transforms.RescaleRelative(
|
|
||||||
scale_range=(0.33 * self.rescale_images,
|
|
||||||
1.33 * self.rescale_images),
|
|
||||||
power_law=True, stretch_range=(0.75, 1.33))
|
|
||||||
|
|
||||||
return transforms.Compose([
|
|
||||||
transforms.NormalizeAnnotations(),
|
|
||||||
# transforms.AnnotationJitter(),
|
|
||||||
transforms.RandomApply(transforms.HFlip(self.CAR_KEYPOINTS, self.HFLIP), 0.5),
|
|
||||||
rescale_t,
|
|
||||||
transforms.RandomApply(transforms.Blur(), self.blur),
|
|
||||||
transforms.RandomChoice(
|
|
||||||
[transforms.RotateBy90(),
|
|
||||||
transforms.RotateUniform(30.0)],
|
|
||||||
[self.orientation_invariant, 0.2],
|
|
||||||
),
|
|
||||||
transforms.Crop(self.square_edge, use_area_of_interest=True),
|
|
||||||
transforms.CenterPad(self.square_edge),
|
|
||||||
transforms.MinSize(min_side=32.0),
|
|
||||||
transforms.TRAIN_TRANSFORM,
|
|
||||||
transforms.Encoders(encoders),
|
|
||||||
])
|
|
||||||
|
|
||||||
def train_loader(self):
|
|
||||||
train_data = CocoLoader(
|
|
||||||
image_dir=self.train_image_dir,
|
|
||||||
ann_file=self.train_annotations,
|
|
||||||
preprocess=self._preprocess(),
|
|
||||||
annotation_filter=True,
|
|
||||||
min_kp_anns=self.min_kp_anns,
|
|
||||||
category_ids=[1],
|
|
||||||
)
|
|
||||||
return torch.utils.data.DataLoader(
|
|
||||||
train_data, batch_size=self.batch_size, shuffle=not self.debug,
|
|
||||||
pin_memory=self.pin_memory, num_workers=self.loader_workers, drop_last=True,
|
|
||||||
collate_fn=collate_images_targets_meta)
|
|
||||||
|
|
||||||
def val_loader(self):
|
|
||||||
val_data = CocoLoader(
|
|
||||||
image_dir=self.val_image_dir,
|
|
||||||
ann_file=self.val_annotations,
|
|
||||||
preprocess=self._preprocess(),
|
|
||||||
annotation_filter=True,
|
|
||||||
min_kp_anns=self.min_kp_anns,
|
|
||||||
category_ids=[1],
|
|
||||||
)
|
|
||||||
return torch.utils.data.DataLoader(
|
|
||||||
val_data, batch_size=self.batch_size, shuffle=False,
|
|
||||||
pin_memory=self.pin_memory, num_workers=self.loader_workers, drop_last=True,
|
|
||||||
collate_fn=collate_images_targets_meta)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def common_eval_preprocess(cls):
|
|
||||||
rescale_t = None
|
|
||||||
if cls.eval_extended_scale:
|
|
||||||
assert cls.eval_long_edge
|
|
||||||
rescale_t = [
|
|
||||||
transforms.DeterministicEqualChoice([
|
|
||||||
transforms.RescaleAbsolute(cls.eval_long_edge),
|
|
||||||
transforms.RescaleAbsolute((cls.eval_long_edge - 1) // 2 + 1),
|
|
||||||
], salt=1)
|
|
||||||
]
|
|
||||||
elif cls.eval_long_edge:
|
|
||||||
rescale_t = transforms.RescaleAbsolute(cls.eval_long_edge)
|
|
||||||
|
|
||||||
if cls.batch_size == 1:
|
|
||||||
padding_t = transforms.CenterPadTight(16)
|
|
||||||
else:
|
|
||||||
assert cls.eval_long_edge
|
|
||||||
padding_t = transforms.CenterPad(cls.eval_long_edge)
|
|
||||||
|
|
||||||
orientation_t = None
|
|
||||||
if cls.eval_orientation_invariant:
|
|
||||||
orientation_t = transforms.DeterministicEqualChoice([
|
|
||||||
None,
|
|
||||||
transforms.RotateBy90(fixed_angle=90),
|
|
||||||
transforms.RotateBy90(fixed_angle=180),
|
|
||||||
transforms.RotateBy90(fixed_angle=270),
|
|
||||||
], salt=3)
|
|
||||||
|
|
||||||
return [
|
|
||||||
transforms.NormalizeAnnotations(),
|
|
||||||
rescale_t,
|
|
||||||
padding_t,
|
|
||||||
orientation_t,
|
|
||||||
]
|
|
||||||
|
|
||||||
def _eval_preprocess(self):
|
|
||||||
return transforms.Compose([
|
|
||||||
*self.common_eval_preprocess(),
|
|
||||||
transforms.ToAnnotations([
|
|
||||||
transforms.ToKpAnnotations(
|
|
||||||
self.CAR_CATEGORIES,
|
|
||||||
keypoints_by_category={1: self.head_metas[0].keypoints},
|
|
||||||
skeleton_by_category={1: self.head_metas[1].skeleton},
|
|
||||||
),
|
|
||||||
transforms.ToCrowdAnnotations(self.CAR_CATEGORIES),
|
|
||||||
]),
|
|
||||||
transforms.EVAL_TRANSFORM,
|
|
||||||
])
|
|
||||||
|
|
||||||
def eval_loader(self):
|
|
||||||
eval_data = CocoLoader(
|
|
||||||
image_dir=self.eval_image_dir,
|
|
||||||
ann_file=self.eval_annotations,
|
|
||||||
preprocess=self._eval_preprocess(),
|
|
||||||
annotation_filter=self.eval_annotation_filter,
|
|
||||||
min_kp_anns=self.min_kp_anns if self.eval_annotation_filter else 0,
|
|
||||||
category_ids=[1] if self.eval_annotation_filter else [],
|
|
||||||
)
|
|
||||||
return torch.utils.data.DataLoader(
|
|
||||||
eval_data, batch_size=self.batch_size, shuffle=False,
|
|
||||||
pin_memory=self.pin_memory, num_workers=self.loader_workers, drop_last=False,
|
|
||||||
collate_fn=collate_images_anns_meta)
|
|
||||||
|
|
||||||
# TODO: make sure that 24kp flag is activated when evaluating a 24kp model
|
|
||||||
def metrics(self):
|
|
||||||
return [metric.Coco(
|
|
||||||
COCO(self.eval_annotations),
|
|
||||||
max_per_image=20,
|
|
||||||
category_ids=[1],
|
|
||||||
iou_type='keypoints',
|
|
||||||
keypoint_oks_sigmas=self.CAR_SIGMAS
|
|
||||||
), MeanPixelError()]
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
import logging
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from openpifpaf.metric.base import Base
|
|
||||||
from openpifpaf.annotation import Annotation
|
|
||||||
|
|
||||||
try:
|
|
||||||
import scipy
|
|
||||||
except ImportError:
|
|
||||||
scipy = None
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class MeanPixelError(Base):
|
|
||||||
"""
|
|
||||||
Calculate mean pixel error and detection rate for a given image
|
|
||||||
and category in an "all-vs-all setting"
|
|
||||||
"""
|
|
||||||
predictions = []
|
|
||||||
image_ids = []
|
|
||||||
errors = [] # mean pixel errors
|
|
||||||
detections = [] # detection rate
|
|
||||||
errors_scaled = [] # mean pixel errors
|
|
||||||
detections_scaled = [] # detection rate
|
|
||||||
px_ref = 368 # CPM crop size in pixels
|
|
||||||
|
|
||||||
def accumulate(self, predictions, image_meta, *, ground_truth=None):
|
|
||||||
errors = []
|
|
||||||
detections = []
|
|
||||||
errors_scaled = []
|
|
||||||
detections_scaled = []
|
|
||||||
|
|
||||||
# Filter ground-truth
|
|
||||||
for annotation in ground_truth:
|
|
||||||
if not isinstance(annotation, Annotation):
|
|
||||||
continue
|
|
||||||
indices_gt = np.nonzero(annotation.data[:, 2] > 1.0)
|
|
||||||
if indices_gt[0].size <= 3:
|
|
||||||
continue
|
|
||||||
gts = annotation.data[indices_gt, 0:2].squeeze()
|
|
||||||
width = float(annotation.fixed_bbox[2])
|
|
||||||
height = float(annotation.fixed_bbox[3])
|
|
||||||
scale = np.array([self.px_ref / width, self.px_ref / height]).reshape(1, 2)
|
|
||||||
|
|
||||||
# Evaluate each keypoint
|
|
||||||
for idx, gt in zip(indices_gt[0], gts):
|
|
||||||
preds = np.array([p.data[idx] for p in predictions]).reshape(-1, 3)[:, 0:2]
|
|
||||||
if preds.size <= 0:
|
|
||||||
continue
|
|
||||||
i = np.argmin(np.linalg.norm(preds - gt, axis=1))
|
|
||||||
dist = preds[i:i + 1] - gt
|
|
||||||
dist_scaled = dist * scale
|
|
||||||
d = float(np.linalg.norm(dist, axis=1))
|
|
||||||
d_scaled = float(np.linalg.norm(dist_scaled, axis=1))
|
|
||||||
|
|
||||||
# Prediction correct if error less than 10 pixels
|
|
||||||
if d < 10:
|
|
||||||
errors.append(d)
|
|
||||||
detections.append(1)
|
|
||||||
else:
|
|
||||||
detections.append(0)
|
|
||||||
if d_scaled < 10:
|
|
||||||
errors_scaled.append(d)
|
|
||||||
detections_scaled.append(1)
|
|
||||||
else:
|
|
||||||
detections_scaled.append(0)
|
|
||||||
|
|
||||||
# Stats for a single image
|
|
||||||
mpe = average(errors)
|
|
||||||
mpe_scaled = average(errors_scaled)
|
|
||||||
det_rate = 100 * average(detections)
|
|
||||||
det_rate_scaled = 100 * average(detections_scaled)
|
|
||||||
LOG.info('Mean Pixel Error (scaled): %s (%s) Det. Rate (scaled): %s (%s)',
|
|
||||||
str(mpe)[:4], str(mpe_scaled)[:4], str(det_rate)[:4], str(det_rate_scaled)[:4])
|
|
||||||
|
|
||||||
# Accumulate stats
|
|
||||||
self.errors.extend(errors)
|
|
||||||
self.detections.extend(detections)
|
|
||||||
self.errors_scaled.extend(errors_scaled)
|
|
||||||
self.detections_scaled.extend(detections_scaled)
|
|
||||||
|
|
||||||
def write_predictions(self, filename, *, additional_data=None):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def stats(self):
|
|
||||||
mpe = average(self.errors)
|
|
||||||
mpe_scaled = average(self.errors_scaled)
|
|
||||||
det_rate = 100 * average(self.detections)
|
|
||||||
det_rate_scaled = 100 * average(self.detections_scaled)
|
|
||||||
LOG.info('Final Results: \nMean Pixel Error [scaled] : %f [%f] '
|
|
||||||
'\nDetection Rate [scaled]: %f [%f]',
|
|
||||||
mpe, mpe_scaled, det_rate, det_rate_scaled)
|
|
||||||
data = {
|
|
||||||
'stats': [mpe, mpe_scaled, det_rate, det_rate_scaled],
|
|
||||||
'text_labels': ['Mean Pixel Error',
|
|
||||||
'Mean Pixel Error Scaled',
|
|
||||||
'Detection Rate [%]',
|
|
||||||
'Detection Rate Scaled[%]'],
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def hungarian_matching(gts, predictions, thresh=0.5):
|
|
||||||
cost = np.zeros((len(gts), len(predictions)))
|
|
||||||
|
|
||||||
for i, (dg, vg) in enumerate(gts):
|
|
||||||
for j, pred in enumerate(predictions):
|
|
||||||
p = np.array(pred.data)
|
|
||||||
dp = p[:, 0:2][vg > 1.0]
|
|
||||||
vp = p[:, 2][vg > 1.0]
|
|
||||||
|
|
||||||
dp[vp < thresh] = -100
|
|
||||||
dp[vp < thresh] = -100
|
|
||||||
|
|
||||||
# measure the per-keypoint distance
|
|
||||||
distances = np.clip(np.linalg.norm(dp - dg, axis=1), 0, 10)
|
|
||||||
cost[i, j] = float(np.mean(distances))
|
|
||||||
|
|
||||||
assert np.max(cost) < 11
|
|
||||||
row, cols = scipy.optimize.linear_sum_assignment(cost)
|
|
||||||
return row, cols, cost
|
|
||||||
|
|
||||||
|
|
||||||
def average(my_list, *, empty_value=0.0):
|
|
||||||
"""calculate mean of a list"""
|
|
||||||
if not my_list:
|
|
||||||
return empty_value
|
|
||||||
|
|
||||||
return sum(my_list) / float(len(my_list))
|
|
||||||
|
Before Width: | Height: | Size: 915 KiB |
@@ -1,133 +0,0 @@
|
|||||||
import cv2
|
|
||||||
import numpy as np
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Read shield with alpha channel
|
|
||||||
def readAlpha(path):
|
|
||||||
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
|
|
||||||
src = cv2.cvtColor(src, cv2.COLOR_BGRA2RGBA)
|
|
||||||
# b, g, r, alpha = cv2.split(src)
|
|
||||||
# dst1 = cv2.merge((b, g, r))
|
|
||||||
# alpha = cv2.cvtColor(alpha, cv2.COLOR_GRAY2BGR)
|
|
||||||
# dst1_64 = dst1.astype(np.float64)
|
|
||||||
# alpha_64 = alpha.astype(np.float64)
|
|
||||||
# alpha_64 *= 1./255.
|
|
||||||
# dst2_64 = np.multiply(dst1_64, alpha_64)
|
|
||||||
# dst2 = dst2_64.astype(np.uint8)
|
|
||||||
return src
|
|
||||||
|
|
||||||
# Read shield with alpha channel and points
|
|
||||||
def readShield(path, step_board=0):
|
|
||||||
pict = readAlpha(path)
|
|
||||||
h_pict = pict.shape[0]
|
|
||||||
w_pict = pict.shape[1]
|
|
||||||
pts_pict = np.array(
|
|
||||||
[[step_board, step_board], [w_pict - step_board, step_board], [w_pict - step_board, h_pict - step_board],
|
|
||||||
[step_board, h_pict - step_board]])
|
|
||||||
return pict, pts_pict
|
|
||||||
|
|
||||||
def ReadShields(shield_album):
|
|
||||||
picts_paths = []
|
|
||||||
f = open(shield_album)
|
|
||||||
for g in f:
|
|
||||||
if g[-1] == '\n':
|
|
||||||
picts_paths.append(g[:-1])
|
|
||||||
else:
|
|
||||||
picts_paths.append(g)
|
|
||||||
f.close()
|
|
||||||
# print(picts_paths)
|
|
||||||
picts = []
|
|
||||||
pts_picts = []
|
|
||||||
for shield_path in picts_paths:
|
|
||||||
pict, pts_pict = readShield(shield_path)
|
|
||||||
picts.append(pict)
|
|
||||||
pts_picts.append(pts_pict)
|
|
||||||
return picts, pts_picts
|
|
||||||
|
|
||||||
def ReadShieldsAni(shield_album):
|
|
||||||
picts_paths = []
|
|
||||||
# filelist = os.listdir(shield_album)
|
|
||||||
# for g in filelist:
|
|
||||||
# picts_paths.append(shield_album + "/" + g)
|
|
||||||
# # print(picts_paths)
|
|
||||||
picts = []
|
|
||||||
pts_picts = []
|
|
||||||
for i in range(0,55):
|
|
||||||
str_i = str(i).zfill(4)
|
|
||||||
pict, pts_pict = readShield(shield_album + "/frame_"+str_i+".png")
|
|
||||||
picts.append(pict)
|
|
||||||
pts_picts.append(pts_pict)
|
|
||||||
return picts, pts_picts
|
|
||||||
|
|
||||||
# Overaling transformed shield on frame
|
|
||||||
def overlaying(pict, img, pts_pict, pts_frame, part=1.0):
|
|
||||||
# Homography
|
|
||||||
# h, status = cv2.findHomography(pts_pict, pts_frame)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# x1 = int(pts_frame[0][1])
|
|
||||||
# if x1 < 0:
|
|
||||||
# x1 = 0
|
|
||||||
# x2 = int(pts_frame[2][1])
|
|
||||||
# y1 = int(pts_frame[0][0])
|
|
||||||
# if y1 < 0:
|
|
||||||
# y1 = 0
|
|
||||||
# y2 = int(pts_frame[2][0])
|
|
||||||
|
|
||||||
(y1, x1), (y2, x2) = pts_frame.min(axis=0), pts_frame.max(axis=0)
|
|
||||||
if (x2 - x1) > 50 and (y2 - y1) > 50:
|
|
||||||
try:
|
|
||||||
area = img[x1:x2, y1:y2]
|
|
||||||
# rows, cols, channels = area.shape
|
|
||||||
|
|
||||||
b, g, r, alpha = cv2.split(pict)
|
|
||||||
pict_rgb = cv2.merge((r, g, b))
|
|
||||||
|
|
||||||
h, status = cv2.findHomography(pts_pict, pts_frame)
|
|
||||||
imgWarp = cv2.warpPerspective(pict_rgb, h, (img.shape[1], img.shape[0]))
|
|
||||||
alphaWarp = cv2.warpPerspective(alpha, h, (img.shape[1], img.shape[0]))
|
|
||||||
pict_area = imgWarp[x1:x2, y1:y2]
|
|
||||||
alpha_area = alphaWarp[x1:x2, y1:y2]
|
|
||||||
|
|
||||||
# pict = cv2.resize(pict, (cols, rows))
|
|
||||||
|
|
||||||
znam = 1./255.
|
|
||||||
alpha_area = cv2.cvtColor(alpha_area, cv2.COLOR_GRAY2BGR)
|
|
||||||
pict_32 = pict_area.astype(np.float32)
|
|
||||||
area_32 = area.astype(np.float32)
|
|
||||||
alpha_32 = alpha_area.astype(np.float32)
|
|
||||||
alpha_32 *= znam
|
|
||||||
if part != 1.:
|
|
||||||
alpha_32 *= part
|
|
||||||
alpha_nega_32 = 1. - alpha_32
|
|
||||||
dst1_32 = np.multiply(pict_32, alpha_32)
|
|
||||||
dst2_32 = np.multiply(area_32, alpha_nega_32)
|
|
||||||
dst_32 = dst1_32 + dst2_32
|
|
||||||
img[x1:x2, y1:y2] = dst_32.astype(np.uint8)
|
|
||||||
|
|
||||||
# Warp transform shield
|
|
||||||
# imgWarp = cv2.warpPerspective(pict_rgb, h, (img.shape[1], img.shape[0]))
|
|
||||||
# alphaWarp = cv2.warpPerspective(alpha, h, (img.shape[1], img.shape[0]))
|
|
||||||
|
|
||||||
# Placing sheild on frame
|
|
||||||
# imgAug = cv2.addWeighted(img, 1.0, imgWarp, 0.5, 0.0)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return img
|
|
||||||
|
|
||||||
def applistShields(album_paths):
|
|
||||||
picts_paths = []
|
|
||||||
picts_names = []
|
|
||||||
f = open(album_paths)
|
|
||||||
for g in f:
|
|
||||||
if g[-1] == '\n':
|
|
||||||
picts_paths.append(g[:-1])
|
|
||||||
else:
|
|
||||||
picts_paths.append(g)
|
|
||||||
f.close()
|
|
||||||
for path in picts_paths:
|
|
||||||
name = path.split('.')[0].split("/")[1]
|
|
||||||
picts_names.append(name)
|
|
||||||
return picts_paths, picts_names
|
|
||||||