updated
|
@ -0,0 +1,54 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
bin/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Rope
|
||||
.ropeproject
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
*.pot
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
This implements a face alignment method, as preprocessing to tasks such as age and gender estimation,
|
||||
and face recognition as described in [1] and [2].
|
||||
|
||||
The code calls an executable of facial landmarks detection, by X.Zhu and D. Ramanan, implementing the algorithm described in [3].
|
||||
|
||||
(The rest of this text is a quotation from their code: Copyright (C) 2012 Xiangxin Zhu, Deva Ramanan)
|
||||
|
||||
It includes pre-trained face models.
|
||||
|
||||
Much of the detection code is built on top of part-based model implementation of [4].
|
||||
|
||||
The training code implements a quadratic program (QP) solver described in [5].
|
||||
|
||||
In the training code, we use the positive samples from MultiPIE dataset (available at www.multipie.org) and the negative images from the INRIAPerson dataset [6] (included in the package).
|
||||
|
||||
Acknowledgements: We graciously thank the authors of the previous code releases and image benchmarks for making them publicly available.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] E. Eidinger, R. Enbar, T. Hassner, Age and Gender Estimation of Unfiltered Faces, submitted to IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY, 2014
|
||||
|
||||
[2] http://www.openu.ac.il/home/hassner/Adience/links.html
|
||||
|
||||
[3] X. Zhu, D. Ramanan. Face Detection, Pose Estimation and Landmark Localization in the Wild. CVPR 2012.
|
||||
|
||||
[4] P. Felzenszwalb, R. Girshick, D. McAllester. Discriminatively Trained Deformable Part Models. http://people.cs.uchicago.edu/~pff/latent.
|
||||
|
||||
[5] D. Ramanan. Dual Coordinate Descent Solvers for Large Structured Prediction Problems. UCI Technical Report, to appear.
|
||||
|
||||
[6] N. Dalal, B. Triggs. Histograms of Oriented Gradients for Human Detection. CVPR 2005.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
Copyright (C) 2014 Adience SER Ltd. (www.adience.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
adience_align
|
||||
========
|
||||
|
||||
This project provides alignment tools for faces, to be used as a preprocessing step before computer vision tasks on face images.
|
||||
|
||||
Homepage for the project: http://www.openu.ac.il/home/hassner/Adience/
|
||||
|
||||
|
||||
See the test for example usage.
|
||||
|
||||
Specificaly, the "pipeline" test, shows how to use the full process (just remember to change the location of the model files to where you stor the *.xml and other model files)
|
||||
|
||||
Installation
|
||||
=========
|
||||
in the root of the repository:
|
||||
|
||||
```
|
||||
python setup.py sdist
|
||||
sudo pip install dist/adience-<version_number>.tar.gz
|
||||
```
|
||||
|
||||
|
||||
|
||||
CopyRight
|
||||
=========
|
||||
(contact: Eran Eidinger (eran@adience.com), Roee Enbar (roee.e@adience.com))
|
||||
|
||||
See the LICENSE.txt file (basically, an MIT license).
|
||||
|
||||
|
||||
With any publication that uses this alignment code, or it's derivative, we kindly ask that you cite the paper:
|
||||
E. Eidinger, R. Enbar, and T. Hassner, Age and Gender Estimation of Unfiltered Faces, Transactions on Information Forensics and Security (IEEE-TIFS), special issue on Face Recognition in the Wild
|
||||
|
||||
For more details, please see:
|
||||
http://www.openu.ac.il/home/hassner/Adience/publications.html
|
||||
|
||||
Compilation notes
|
||||
========
|
||||
1. The shared objects were compiled for linux 64bit on Ubuntu 13.10
|
||||
2. The SO uses boost-1.53, so make sure it is installed on your system and available at /usr/local/, or use LD_LIBRARY_PATH="yourpath" to point it at the right place. Alternatively, place "libboost_system.so.1.53.0" and "libboost_filesystem.so.1.53.0". at the "adiencealign/resources/" subfolder
|
||||
3. For landmarks detection, we use the file libPartsBasedDetector.so, compiled from the project https://github.com/wg-perception/PartsBasedDetector. You can either compile it yourselves, or use the version under "resources" subfolder, compiled with boost 1.53, on a linux ubuntu 14.04 machine.
|
||||
|
||||
We will release the source code for the shared object in the near future
|
||||
|
||||
Running the test
|
||||
========
|
||||
1. run ```./clear_test.sh``` to delete results of old tests.
|
||||
2. run ```python test_pipeline.py```
|
||||
3. results are in the "outputs" subfolder
|
|
@ -0,0 +1,20 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
from adiencealign.common.landmarks import fidu_transform, shift_vector,\
|
||||
WEIGHTS3
|
||||
|
||||
class AffineAligner(object):
|
||||
def __init__(self, fidu_model_file, ):
|
||||
|
||||
self.shift = ( 0.25, 0.25 )
|
||||
fidu_model = [(int(x.split(',')[1]),int(x.split(',')[2])) for x in file(fidu_model_file,'r')]
|
||||
self.fidu_model = shift_vector(fidu_model, self.shift)
|
||||
self.WEIGHTS3 = WEIGHTS3
|
||||
|
||||
def align(self, img, fidu_points):
|
||||
# create bs1 image
|
||||
funneled_img, R = fidu_transform(self.fidu_model, fidu_points, WEIGHTS3, img, self.shift)
|
||||
return funneled_img, R
|
|
@ -0,0 +1,354 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import cv2
|
||||
import pickle
|
||||
import numpy as np
|
||||
from shapely.geometry.polygon import Polygon
|
||||
import math
|
||||
from adiencealign.common.files import make_path, expand_path
|
||||
from adiencealign.common.images import pad_image_for_rotation
|
||||
|
||||
class CascadeDetector(object):
|
||||
'''
|
||||
This is a haar cascade classifier capable of detecting in multiple angles
|
||||
'''
|
||||
def __init__(self, cascade_file = './resources/haarcascade_frontalface_default.xml',
|
||||
min_size = (10, 10),
|
||||
min_neighbors = 20,
|
||||
scale_factor = 1.04,
|
||||
angles = [0],
|
||||
thr = 0.4,
|
||||
cascade_type = 'haar'):
|
||||
'''
|
||||
cascade_type - is a string defining the type of cascade
|
||||
'''
|
||||
print(expand_path('.'))
|
||||
self.cascade_file = cascade_file.rsplit('/',1)[1]
|
||||
self._cascade_classifier = cv2.CascadeClassifier(cascade_file)
|
||||
self.scale_factor = scale_factor
|
||||
self.min_neighbors = min_neighbors
|
||||
self.min_size = min_size
|
||||
self.cascade_type = cascade_type
|
||||
self.angles = angles
|
||||
self.thr = thr
|
||||
|
||||
def __str__(self):
|
||||
return ''.join([str(x) for x in ['cascade_file:',self.cascade_file,
|
||||
',scale_factor:',self.scale_factor,
|
||||
',min_neighbors:',self.min_neighbors,
|
||||
',min_neighbors:',self.min_neighbors,
|
||||
',cascade_type:',self.cascade_type
|
||||
]])
|
||||
|
||||
def save_configuration(self, target_file):
|
||||
file_path = target_file.rsplit('/',1)[0]
|
||||
make_path(file_path)
|
||||
config = {'min_size':self.min_size, 'min_neighbours':self.min_neighbors, 'scale_factor':self.scale_factor, 'cascade_file':self.cascade_file}
|
||||
pickle.dump(obj=config, file = open(target_file,'w'), protocol = 2)
|
||||
|
||||
@staticmethod
|
||||
def load_configuration(target_file):
|
||||
return pickle.load(open(target_file,'r'))
|
||||
|
||||
def detectMultiScaleWithScores(self, img, scaleFactor = None, minNeighbors = None, minSize = None, flags = 4):
|
||||
scaleFactor = self.scale_factor if not scaleFactor else scaleFactor
|
||||
minNeighbors = self.min_neighbors if not minNeighbors else minNeighbors
|
||||
minSize = self.min_size if not minSize else minSize
|
||||
return self._cascade_classifier.detectMultiScale(img,
|
||||
scaleFactor = scaleFactor,
|
||||
minNeighbors = minNeighbors,
|
||||
minSize = minSize,
|
||||
flags = flags)
|
||||
|
||||
def detectWithAngles(self, img, angels = None, resolve = True, thr = None ):
|
||||
'''
|
||||
angles - a list of angles to test. If None, default to the value created at the constructor (which defaults to [0])
|
||||
resolve - a boolean flag, whether or not to cluster the boxes, and resolve cluster by highest score.
|
||||
thr - the maximum area covered with objects, before we break from the angles loop
|
||||
|
||||
returns - a list of CascadeResult() objects
|
||||
'''
|
||||
|
||||
if thr == None:
|
||||
thr = self.thr
|
||||
|
||||
original_size = img.shape[0] * img.shape[0]
|
||||
if angels == None:
|
||||
angels = self.angles
|
||||
|
||||
results = []
|
||||
total_area = 0
|
||||
for angle in angels:
|
||||
|
||||
# the diagonal of the image is the diameter of the rotated image, so the big_image needs to bound this circle
|
||||
# by being that big
|
||||
|
||||
big_image, x_shift, y_shift, diag, rot_center = pad_image_for_rotation(img)
|
||||
|
||||
# find the rotation and the inverse rotation matrix, to allow translations between old and new coordinates and vice versa
|
||||
rot_mat = cv2.getRotationMatrix2D(rot_center, angle, scale = 1.0)
|
||||
inv_rot_mat = cv2.invertAffineTransform(rot_mat)
|
||||
|
||||
# rotate the image by the desired angle
|
||||
rot_image = cv2.warpAffine(big_image, rot_mat, (big_image.shape[1],big_image.shape[0]), flags=cv2.INTER_CUBIC)
|
||||
faces = self.detectMultiScaleWithScores(rot_image, scaleFactor = 1.03, minNeighbors = 20, minSize = (15,15), flags = 4)
|
||||
for face in faces:
|
||||
xp = face[0]
|
||||
dx = face[2]
|
||||
yp = face[1]
|
||||
dy = face[3]
|
||||
score = 1
|
||||
dots = np.matrix([[xp,xp+dx,xp+dx,xp], [yp,yp,yp+dy,yp+dy], [1, 1, 1, 1]])
|
||||
# these are the original coordinates in the "big_image"
|
||||
# print dots
|
||||
originals_in_big = inv_rot_mat * dots
|
||||
# print originals_in_big
|
||||
shifter = np.matrix([[x_shift]*4, [y_shift]*4])
|
||||
# print shifter
|
||||
# these are the original coordinate in the original image
|
||||
originals = originals_in_big - shifter
|
||||
# print originals
|
||||
points = np.array(originals.transpose())
|
||||
x = points[0,0]
|
||||
y = points[0,1]
|
||||
box_with_score = ([x,y,dx,dy], score)
|
||||
|
||||
cascade_result = CascadeResult.from_polygon_points(points, score, self.cascade_type)
|
||||
# print cascade_result
|
||||
|
||||
results.append(cascade_result)
|
||||
|
||||
#################
|
||||
# test and see, if we found enough objects, break out and don't waste our time
|
||||
total_area += cascade_result.area
|
||||
|
||||
if resolve:
|
||||
return resolve_angles(results, width = img.shape[1], height = img.shape[0])
|
||||
else:
|
||||
return results
|
||||
|
||||
class BoxInImage(object):
|
||||
def __init__(self, originals, dx, dy, score = None, angle = 0):
|
||||
self.originals = originals
|
||||
self.dx = dx
|
||||
self.dy = dy
|
||||
self.score = score
|
||||
self.angle = angle
|
||||
|
||||
def __str__(self):
|
||||
return ",".join([str(x) for x in [self.originals, self.dx, self.dy, self.score, self.angle]])
|
||||
|
||||
def resolve_angles(list_of_results, width, height, thr = 0.3):
|
||||
'''
|
||||
we want to cluster the boxes into clusters, and then choose the best box in each cluster by score
|
||||
* thr - decides what the maximum distance is for a box to join a cluster, in the sense of how much of it's area is covered by the best box in the cluster
|
||||
note, that two squares, centered, with 45 degrees rotation, will overlap on 77% of their area (thr == 0.22)
|
||||
'''
|
||||
clusters = []
|
||||
for box in list_of_results:
|
||||
# total_polygon = Polygon([(0,0), (width,0), (width,height), (0,height)])
|
||||
# if box.polygon.intersection(total_polygon).area < box.area:
|
||||
# # this means the box is outside the image somehow
|
||||
# continue
|
||||
|
||||
area = box.area
|
||||
closest_cluster = None
|
||||
dist_to_closest_cluster = 1.0
|
||||
for n,cluster in enumerate(clusters):
|
||||
dist = 1.0
|
||||
for cluster_box in cluster:
|
||||
local_dist = 1.0 - box.overlap(cluster_box)/area
|
||||
dist = min(dist, local_dist)
|
||||
if dist < dist_to_closest_cluster:
|
||||
dist_to_closest_cluster = dist
|
||||
closest_cluster = n
|
||||
if closest_cluster == None or dist_to_closest_cluster > thr:
|
||||
# no good cluster was found, open a new cluster
|
||||
clusters.append([box])
|
||||
else:
|
||||
clusters[n].append(box)
|
||||
|
||||
centroids = []
|
||||
for cluster in clusters:
|
||||
centroids.append(sorted(cluster,key=lambda x: x.score)[-1])
|
||||
|
||||
return centroids
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def resolve_boxes(dict_of_list_of_cascade_results, min_overlap = 0.7):
|
||||
'''
|
||||
Say you tried two different cascades to detect faces.
|
||||
enter a dictionary (the key is a string describing a cascade type) of detected objects
|
||||
This function returns a unified results list, where it resolves overlapping boxes, and chooses one of them.
|
||||
|
||||
The bigger boxes are selected instead of smaller ones, whether they contain them, or enough of them, determined by min_overlap
|
||||
|
||||
'''
|
||||
final_faces = []
|
||||
for cascade_str, faces in dict_of_list_of_cascade_results.items():
|
||||
# go through each cascade type
|
||||
for face in faces:
|
||||
if type(face) == CascadeResult:
|
||||
new_res = face
|
||||
else:
|
||||
new_res = CascadeResult(face,cascade_type = cascade_str)
|
||||
to_add = True
|
||||
for old_index,old_res in enumerate(final_faces):
|
||||
ratio = new_res.area / old_res.area
|
||||
if ratio >1.0:
|
||||
# new_box is bigger
|
||||
if new_res.overlap(old_res)/old_res.area > min_overlap:
|
||||
# the new box contains the old one, we want to replace it:
|
||||
final_faces[old_index] = new_res
|
||||
to_add = False
|
||||
break
|
||||
if ratio <=1.0:
|
||||
# the new_box is smaller
|
||||
if new_res.overlap(old_res)/new_res.area > min_overlap:
|
||||
# the old box contains the new one, we therefore dont need to add the new box:
|
||||
to_add = False
|
||||
break
|
||||
if to_add:
|
||||
# if there was no hit, this is a new face, we can add it
|
||||
final_faces.append(new_res)
|
||||
return final_faces
|
||||
|
||||
def most_centered_box( cascade_results, xxx_todo_changeme ):
|
||||
( rows, cols ) = xxx_todo_changeme
|
||||
best_err = 1e10
|
||||
for i, cascade in enumerate( cascade_results ):
|
||||
err = ( cascade.x + cascade.dx / 2 - cols / 2 ) ** 2 + ( cascade.y + cascade.dy / 2 - rows / 2 ) ** 2
|
||||
if err < best_err:
|
||||
index = i
|
||||
return cascade_results[ index ]
|
||||
|
||||
class CascadeResult(object):
|
||||
def __init__(self, box_with_score, cascade_type = None, angle = 0):
|
||||
self.x = box_with_score[0][0]
|
||||
self.y = box_with_score[0][1]
|
||||
self.dx = box_with_score[0][2]
|
||||
self.dy = box_with_score[0][3]
|
||||
self.score = box_with_score[1]
|
||||
self.cascade_type = cascade_type
|
||||
self.angle = angle
|
||||
|
||||
@staticmethod
|
||||
def from_polygon_points(points, score, cascade_type = None):
|
||||
'''
|
||||
an alternative generator, allows giving the polygon points instead of [x,y,dx,dy]
|
||||
'''
|
||||
x = points[0,0]
|
||||
y = points[0,1]
|
||||
top = points[1,] - points[0,]
|
||||
left = points[3,] - points[0,]
|
||||
dx = math.sqrt(sum([i*i for i in top]))
|
||||
dy = math.sqrt(sum([i*i for i in left]))
|
||||
angle = math.atan(float(top[1])/top[0]) * 180 / math.pi if top[0] != 0 else (970 if top[1] >0 else -90)
|
||||
return CascadeResult(([x,y,dx,dy],score), cascade_type, angle)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return ''.join([str(x) for x in ['center:',self.center,
|
||||
',\nx:',self.x,
|
||||
',\ny:',self.y,
|
||||
',\ndx:',self.dx,
|
||||
',\ndy:',self.dy,
|
||||
',\nscore:',self.score,
|
||||
',\nangle:',self.angle,
|
||||
',\ncascade_type:',self.cascade_type,
|
||||
',\npoints_int:\n',self.points_int
|
||||
]])
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
x = self.x
|
||||
y = self.y
|
||||
dx = self.dx
|
||||
dy = self.dy
|
||||
a = self.angle/180.0*math.pi
|
||||
dots = np.matrix([[x,y,1],[x+dx,y,1],[x+dx,y+dy,1],[x,y+dy,1]])
|
||||
dots = dots.transpose()
|
||||
rot_mat = cv2.getRotationMatrix2D((dots[0,0],dots[1,0]), -self.angle, scale = 1.0)
|
||||
points = rot_mat * dots
|
||||
points = points.transpose()
|
||||
return points
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return tuple(int(x) for x in (self.points.sum(0)/4.0).tolist()[0])
|
||||
|
||||
@property
|
||||
def points_int(self):
|
||||
return self.points.astype(int)
|
||||
|
||||
@property
|
||||
def score_with_type(self):
|
||||
if self.cascade_type:
|
||||
return self.cascade_type + ' ' + str(self.score)
|
||||
else:
|
||||
return str(self.score)
|
||||
|
||||
@property
|
||||
def filename_encode(self):
|
||||
|
||||
return '_'.join([str(x) for x in ['loct'] + self.cvformat_result[0] + ['ang', int(self.angle),self.cascade_type, self.score]])
|
||||
|
||||
@property
|
||||
def cvformat_coords(self):
|
||||
if self.angle == 0:
|
||||
return [int(x) for x in [self.x, self.y, self.dx, self.dy]]
|
||||
else:
|
||||
raise Exception('cannot return [x,y,dx,dy] for a box with angle, use cvformat_result() instead')
|
||||
|
||||
@property
|
||||
def cvformat_result(self):
|
||||
return ([int(x) for x in [self.x, self.y, self.dx, self.dy]], self.score, self.angle)
|
||||
|
||||
# @property
|
||||
# def rot_matrix(self):
|
||||
# return array([[cos(math.radians(self.angle)), -sin(math.radians(self.angle))],
|
||||
# [sin(math.radians(self.angle)), cos(math.radians(self.angle))]])
|
||||
|
||||
@property
|
||||
def top_left(self):
|
||||
return tuple(self.points[0,].tolist()[0])
|
||||
|
||||
@property
|
||||
def top_right(self):
|
||||
return tuple(self.points[1,].tolist()[0])
|
||||
|
||||
@property
|
||||
def bottom_right(self):
|
||||
return tuple(self.points[2,].tolist()[0])
|
||||
|
||||
@property
|
||||
def bottom_left(self):
|
||||
return tuple(self.points[3,].tolist()[0])
|
||||
|
||||
@property
|
||||
def polygon(self):
|
||||
return Polygon([self.top_left, self.top_right, self.bottom_right, self.bottom_left])
|
||||
|
||||
def overlap(self, otherRect):
|
||||
return float(self.polygon.intersection(otherRect.polygon).area)
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
return float(self.polygon.area)
|
||||
|
||||
def __gt__(self,b):
|
||||
return self.area>b.area
|
||||
def __ge__(self,b):
|
||||
return self.area>=b.area
|
||||
def __lt__(self,b):
|
||||
return self.area<b.area
|
||||
def __le__(self,b):
|
||||
return self.area<=b.area
|
||||
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import cv2
|
||||
import pickle
|
||||
import numpy as np
|
||||
from shapely.geometry.polygon import Polygon
|
||||
import math
|
||||
from adiencealign.common.files import make_path, expand_path
|
||||
from adiencealign.common.images import pad_image_for_rotation
|
||||
|
||||
class CascadeDetector(object):
|
||||
'''
|
||||
This is a haar cascade classifier capable of detecting in multiple angles
|
||||
'''
|
||||
def __init__(self, cascade_file = './resources/haarcascade_frontalface_default.xml',
|
||||
min_size = (10, 10),
|
||||
min_neighbors = 20,
|
||||
scale_factor = 1.04,
|
||||
angles = [0],
|
||||
thr = 0.4,
|
||||
cascade_type = 'haar'):
|
||||
'''
|
||||
cascade_type - is a string defining the type of cascade
|
||||
'''
|
||||
print expand_path('.')
|
||||
self.cascade_file = cascade_file.rsplit('/',1)[1]
|
||||
self._cascade_classifier = cv2.CascadeClassifier(cascade_file)
|
||||
self.scale_factor = scale_factor
|
||||
self.min_neighbors = min_neighbors
|
||||
self.min_size = min_size
|
||||
self.cascade_type = cascade_type
|
||||
self.angles = angles
|
||||
self.thr = thr
|
||||
|
||||
def __str__(self):
|
||||
return ''.join([str(x) for x in ['cascade_file:',self.cascade_file,
|
||||
',scale_factor:',self.scale_factor,
|
||||
',min_neighbors:',self.min_neighbors,
|
||||
',min_neighbors:',self.min_neighbors,
|
||||
',cascade_type:',self.cascade_type
|
||||
]])
|
||||
|
||||
def save_configuration(self, target_file):
|
||||
file_path = target_file.rsplit('/',1)[0]
|
||||
make_path(file_path)
|
||||
config = {'min_size':self.min_size, 'min_neighbours':self.min_neighbors, 'scale_factor':self.scale_factor, 'cascade_file':self.cascade_file}
|
||||
pickle.dump(obj=config, file = open(target_file,'w'), protocol = 2)
|
||||
|
||||
@staticmethod
|
||||
def load_configuration(target_file):
|
||||
return pickle.load(open(target_file,'r'))
|
||||
|
||||
def detectMultiScaleWithScores(self, img, scaleFactor = None, minNeighbors = None, minSize = None, flags = 4):
|
||||
scaleFactor = self.scale_factor if not scaleFactor else scaleFactor
|
||||
minNeighbors = self.min_neighbors if not minNeighbors else minNeighbors
|
||||
minSize = self.min_size if not minSize else minSize
|
||||
return self._cascade_classifier.detectMultiScale(img,
|
||||
scaleFactor = scaleFactor,
|
||||
minNeighbors = minNeighbors,
|
||||
minSize = minSize,
|
||||
flags = flags)
|
||||
|
||||
def detectWithAngles(self, img, angels = None, resolve = True, thr = None ):
|
||||
'''
|
||||
angles - a list of angles to test. If None, default to the value created at the constructor (which defaults to [0])
|
||||
resolve - a boolean flag, whether or not to cluster the boxes, and resolve cluster by highest score.
|
||||
thr - the maximum area covered with objects, before we break from the angles loop
|
||||
|
||||
returns - a list of CascadeResult() objects
|
||||
'''
|
||||
|
||||
if thr == None:
|
||||
thr = self.thr
|
||||
|
||||
original_size = img.shape[0] * img.shape[0]
|
||||
if angels == None:
|
||||
angels = self.angles
|
||||
|
||||
results = []
|
||||
total_area = 0
|
||||
for angle in angels:
|
||||
|
||||
# the diagonal of the image is the diameter of the rotated image, so the big_image needs to bound this circle
|
||||
# by being that big
|
||||
|
||||
big_image, x_shift, y_shift, diag, rot_center = pad_image_for_rotation(img)
|
||||
|
||||
# find the rotation and the inverse rotation matrix, to allow translations between old and new coordinates and vice versa
|
||||
rot_mat = cv2.getRotationMatrix2D(rot_center, angle, scale = 1.0)
|
||||
inv_rot_mat = cv2.invertAffineTransform(rot_mat)
|
||||
|
||||
# rotate the image by the desired angle
|
||||
rot_image = cv2.warpAffine(big_image, rot_mat, (big_image.shape[1],big_image.shape[0]), flags=cv2.INTER_CUBIC)
|
||||
faces = self.detectMultiScaleWithScores(rot_image, scaleFactor = 1.03, minNeighbors = 20, minSize = (15,15), flags = 4)
|
||||
for face in faces:
|
||||
xp = face[0]
|
||||
dx = face[2]
|
||||
yp = face[1]
|
||||
dy = face[3]
|
||||
score = 1
|
||||
dots = np.matrix([[xp,xp+dx,xp+dx,xp], [yp,yp,yp+dy,yp+dy], [1, 1, 1, 1]])
|
||||
# these are the original coordinates in the "big_image"
|
||||
# print dots
|
||||
originals_in_big = inv_rot_mat * dots
|
||||
# print originals_in_big
|
||||
shifter = np.matrix([[x_shift]*4, [y_shift]*4])
|
||||
# print shifter
|
||||
# these are the original coordinate in the original image
|
||||
originals = originals_in_big - shifter
|
||||
# print originals
|
||||
points = np.array(originals.transpose())
|
||||
x = points[0,0]
|
||||
y = points[0,1]
|
||||
box_with_score = ([x,y,dx,dy], score)
|
||||
|
||||
cascade_result = CascadeResult.from_polygon_points(points, score, self.cascade_type)
|
||||
# print cascade_result
|
||||
|
||||
results.append(cascade_result)
|
||||
|
||||
#################
|
||||
# test and see, if we found enough objects, break out and don't waste our time
|
||||
total_area += cascade_result.area
|
||||
|
||||
if resolve:
|
||||
return resolve_angles(results, width = img.shape[1], height = img.shape[0])
|
||||
else:
|
||||
return results
|
||||
|
||||
class BoxInImage(object):
|
||||
def __init__(self, originals, dx, dy, score = None, angle = 0):
|
||||
self.originals = originals
|
||||
self.dx = dx
|
||||
self.dy = dy
|
||||
self.score = score
|
||||
self.angle = angle
|
||||
|
||||
def __str__(self):
|
||||
return ",".join([str(x) for x in [self.originals, self.dx, self.dy, self.score, self.angle]])
|
||||
|
||||
def resolve_angles(list_of_results, width, height, thr = 0.3):
|
||||
'''
|
||||
we want to cluster the boxes into clusters, and then choose the best box in each cluster by score
|
||||
* thr - decides what the maximum distance is for a box to join a cluster, in the sense of how much of it's area is covered by the best box in the cluster
|
||||
note, that two squares, centered, with 45 degrees rotation, will overlap on 77% of their area (thr == 0.22)
|
||||
'''
|
||||
clusters = []
|
||||
for box in list_of_results:
|
||||
# total_polygon = Polygon([(0,0), (width,0), (width,height), (0,height)])
|
||||
# if box.polygon.intersection(total_polygon).area < box.area:
|
||||
# # this means the box is outside the image somehow
|
||||
# continue
|
||||
|
||||
area = box.area
|
||||
closest_cluster = None
|
||||
dist_to_closest_cluster = 1.0
|
||||
for n,cluster in enumerate(clusters):
|
||||
dist = 1.0
|
||||
for cluster_box in cluster:
|
||||
local_dist = 1.0 - box.overlap(cluster_box)/area
|
||||
dist = min(dist, local_dist)
|
||||
if dist < dist_to_closest_cluster:
|
||||
dist_to_closest_cluster = dist
|
||||
closest_cluster = n
|
||||
if closest_cluster == None or dist_to_closest_cluster > thr:
|
||||
# no good cluster was found, open a new cluster
|
||||
clusters.append([box])
|
||||
else:
|
||||
clusters[n].append(box)
|
||||
|
||||
centroids = []
|
||||
for cluster in clusters:
|
||||
centroids.append(sorted(cluster,key=lambda x: x.score)[-1])
|
||||
|
||||
return centroids
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def resolve_boxes(dict_of_list_of_cascade_results, min_overlap = 0.7):
|
||||
'''
|
||||
Say you tried two different cascades to detect faces.
|
||||
enter a dictionary (the key is a string describing a cascade type) of detected objects
|
||||
This function returns a unified results list, where it resolves overlapping boxes, and chooses one of them.
|
||||
|
||||
The bigger boxes are selected instead of smaller ones, whether they contain them, or enough of them, determined by min_overlap
|
||||
|
||||
'''
|
||||
final_faces = []
|
||||
for cascade_str, faces in dict_of_list_of_cascade_results.iteritems():
|
||||
# go through each cascade type
|
||||
for face in faces:
|
||||
if type(face) == CascadeResult:
|
||||
new_res = face
|
||||
else:
|
||||
new_res = CascadeResult(face,cascade_type = cascade_str)
|
||||
to_add = True
|
||||
for old_index,old_res in enumerate(final_faces):
|
||||
ratio = new_res.area / old_res.area
|
||||
if ratio >1.0:
|
||||
# new_box is bigger
|
||||
if new_res.overlap(old_res)/old_res.area > min_overlap:
|
||||
# the new box contains the old one, we want to replace it:
|
||||
final_faces[old_index] = new_res
|
||||
to_add = False
|
||||
break
|
||||
if ratio <=1.0:
|
||||
# the new_box is smaller
|
||||
if new_res.overlap(old_res)/new_res.area > min_overlap:
|
||||
# the old box contains the new one, we therefore dont need to add the new box:
|
||||
to_add = False
|
||||
break
|
||||
if to_add:
|
||||
# if there was no hit, this is a new face, we can add it
|
||||
final_faces.append(new_res)
|
||||
return final_faces
|
||||
|
||||
def most_centered_box( cascade_results, ( rows, cols ) ):
|
||||
best_err = 1e10
|
||||
for i, cascade in enumerate( cascade_results ):
|
||||
err = ( cascade.x + cascade.dx / 2 - cols / 2 ) ** 2 + ( cascade.y + cascade.dy / 2 - rows / 2 ) ** 2
|
||||
if err < best_err:
|
||||
index = i
|
||||
return cascade_results[ index ]
|
||||
|
||||
class CascadeResult(object):
|
||||
def __init__(self, box_with_score, cascade_type = None, angle = 0):
|
||||
self.x = box_with_score[0][0]
|
||||
self.y = box_with_score[0][1]
|
||||
self.dx = box_with_score[0][2]
|
||||
self.dy = box_with_score[0][3]
|
||||
self.score = box_with_score[1]
|
||||
self.cascade_type = cascade_type
|
||||
self.angle = angle
|
||||
|
||||
@staticmethod
|
||||
def from_polygon_points(points, score, cascade_type = None):
|
||||
'''
|
||||
an alternative generator, allows giving the polygon points instead of [x,y,dx,dy]
|
||||
'''
|
||||
x = points[0,0]
|
||||
y = points[0,1]
|
||||
top = points[1,] - points[0,]
|
||||
left = points[3,] - points[0,]
|
||||
dx = math.sqrt(sum([i*i for i in top]))
|
||||
dy = math.sqrt(sum([i*i for i in left]))
|
||||
angle = math.atan(float(top[1])/top[0]) * 180 / math.pi if top[0] != 0 else (970 if top[1] >0 else -90)
|
||||
return CascadeResult(([x,y,dx,dy],score), cascade_type, angle)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return ''.join([str(x) for x in ['center:',self.center,
|
||||
',\nx:',self.x,
|
||||
',\ny:',self.y,
|
||||
',\ndx:',self.dx,
|
||||
',\ndy:',self.dy,
|
||||
',\nscore:',self.score,
|
||||
',\nangle:',self.angle,
|
||||
',\ncascade_type:',self.cascade_type,
|
||||
',\npoints_int:\n',self.points_int
|
||||
]])
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
x = self.x
|
||||
y = self.y
|
||||
dx = self.dx
|
||||
dy = self.dy
|
||||
a = self.angle/180.0*math.pi
|
||||
dots = np.matrix([[x,y,1],[x+dx,y,1],[x+dx,y+dy,1],[x,y+dy,1]])
|
||||
dots = dots.transpose()
|
||||
rot_mat = cv2.getRotationMatrix2D((dots[0,0],dots[1,0]), -self.angle, scale = 1.0)
|
||||
points = rot_mat * dots
|
||||
points = points.transpose()
|
||||
return points
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return tuple(int(x) for x in (self.points.sum(0)/4.0).tolist()[0])
|
||||
|
||||
@property
|
||||
def points_int(self):
|
||||
return self.points.astype(int)
|
||||
|
||||
@property
|
||||
def score_with_type(self):
|
||||
if self.cascade_type:
|
||||
return self.cascade_type + ' ' + str(self.score)
|
||||
else:
|
||||
return str(self.score)
|
||||
|
||||
@property
|
||||
def filename_encode(self):
|
||||
|
||||
return '_'.join([str(x) for x in ['loct'] + self.cvformat_result[0] + ['ang', int(self.angle),self.cascade_type, self.score]])
|
||||
|
||||
@property
|
||||
def cvformat_coords(self):
|
||||
if self.angle == 0:
|
||||
return [int(x) for x in [self.x, self.y, self.dx, self.dy]]
|
||||
else:
|
||||
raise Exception('cannot return [x,y,dx,dy] for a box with angle, use cvformat_result() instead')
|
||||
|
||||
@property
|
||||
def cvformat_result(self):
|
||||
return ([int(x) for x in [self.x, self.y, self.dx, self.dy]], self.score, self.angle)
|
||||
|
||||
# @property
|
||||
# def rot_matrix(self):
|
||||
# return array([[cos(math.radians(self.angle)), -sin(math.radians(self.angle))],
|
||||
# [sin(math.radians(self.angle)), cos(math.radians(self.angle))]])
|
||||
|
||||
@property
|
||||
def top_left(self):
|
||||
return tuple(self.points[0,].tolist()[0])
|
||||
|
||||
@property
|
||||
def top_right(self):
|
||||
return tuple(self.points[1,].tolist()[0])
|
||||
|
||||
@property
|
||||
def bottom_right(self):
|
||||
return tuple(self.points[2,].tolist()[0])
|
||||
|
||||
@property
|
||||
def bottom_left(self):
|
||||
return tuple(self.points[3,].tolist()[0])
|
||||
|
||||
@property
|
||||
def polygon(self):
|
||||
return Polygon([self.top_left, self.top_right, self.bottom_right, self.bottom_left])
|
||||
|
||||
def overlap(self, otherRect):
|
||||
return float(self.polygon.intersection(otherRect.polygon).area)
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
return float(self.polygon.area)
|
||||
|
||||
def __gt__(self,b):
|
||||
return self.area>b.area
|
||||
def __ge__(self,b):
|
||||
return self.area>=b.area
|
||||
def __lt__(self,b):
|
||||
return self.area<b.area
|
||||
def __le__(self,b):
|
||||
return self.area<=b.area
|
||||
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
from adiencealign.common.images import extract_box
|
||||
import glob
|
||||
import os
|
||||
import time
|
||||
from adiencealign.cascade_detection.cascade_detector import CascadeDetector,\
|
||||
resolve_boxes, CascadeResult
|
||||
import cv2
|
||||
import csv
|
||||
'''
|
||||
Created on Dec 18, 2013
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
'''
|
||||
Created on Nov 26, 2013
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
|
||||
class CascadeFaceFinder(object):
|
||||
|
||||
def __init__(self,
|
||||
min_size = 32,
|
||||
drawn_target_res = 360*360,
|
||||
hangles = [0, -22, 22],
|
||||
langles = [0,-45,-22,22,45],
|
||||
haar_file = 'haarcascade_frontalface_default.xml',
|
||||
lbp_file = 'lbpcascade_frontalface.xml'):
|
||||
'''
|
||||
finder = CascadeFaceFinder(min_size = 32, drawn_target_res = 360*360, hangles = [0], langles = [0,-45,-22,22,45], parts_threshold = 0)
|
||||
|
||||
finder.get_faces_in_folder(input_folder, output_dir, drawn_folder, is_small_drawn)
|
||||
|
||||
or
|
||||
|
||||
finder.get_faces_in_photo(full_file, output_dir, drawn_folder, is_small_drawn)
|
||||
'''
|
||||
self.min_size = (min_size,min_size)
|
||||
self.drawn_target_res = drawn_target_res
|
||||
self._hangles = hangles
|
||||
self._langles = langles
|
||||
self.recalc_detectors(haar_file, lbp_file)
|
||||
|
||||
# self.funnel = FaceFunnel()
|
||||
|
||||
@property
|
||||
def hangles(self):
|
||||
return self._hangles
|
||||
|
||||
@hangles.setter
|
||||
def hangles(self,hangles):
|
||||
self._hangles = hangles
|
||||
self.recalc_detectors()
|
||||
|
||||
@property
|
||||
def langles(self):
|
||||
return self._langles
|
||||
|
||||
@langles.setter
|
||||
def langles(self,langles):
|
||||
self._langles = langles
|
||||
self.recalc_detectors()
|
||||
|
||||
def recalc_detectors(self, haar_file, lbp_file):
|
||||
self.haar_dtct = CascadeDetector(cascade_file = haar_file,
|
||||
min_size = self.min_size,
|
||||
min_neighbors = 20,
|
||||
scale_factor = 1.03,
|
||||
cascade_type = 'haar',
|
||||
thr = 0.4,
|
||||
angles = self.hangles)
|
||||
|
||||
self.lbp_dtct = CascadeDetector(cascade_file = lbp_file,
|
||||
min_size = self.min_size,
|
||||
min_neighbors = 15,
|
||||
scale_factor = 1.04,
|
||||
cascade_type = 'lbp',
|
||||
thr = 0.4,
|
||||
angles = self.langles)
|
||||
|
||||
|
||||
def get_faces_list_in_photo(self, img):
|
||||
if self.hangles:
|
||||
haar_faces = self.haar_dtct.detectWithAngles(img, resolve = True)
|
||||
else:
|
||||
haar_faces = []
|
||||
lbp_faces = self.lbp_dtct.detectWithAngles(img, resolve = True)
|
||||
faces = resolve_boxes({'haar':haar_faces, 'lbp':lbp_faces}, min_overlap = 0.6)
|
||||
|
||||
return faces
|
||||
|
||||
def create_faces_file(self, fname, is_overwrite = False, target_file = None):
|
||||
'''
|
||||
Runs facial detection on fname (say a.jpg, or a.png), and creates a results file (a.faces.txt)
|
||||
|
||||
target_file - override, and specify a specific target file
|
||||
is_overwrite - allow overwriting an existing results file
|
||||
'''
|
||||
faces = self.get_faces_list_in_photo(cv2.imread(fname))
|
||||
results_file = fname.rsplit('.',1)[0] + '.faces.txt' if target_file is None else target_file
|
||||
|
||||
if os.path.exists(results_file) and not is_overwrite:
|
||||
print("Warning, faces result file", results_file, "exists")
|
||||
else:
|
||||
with open(results_file,'w') as csvfile:
|
||||
csv_writer = csv.writer(csvfile, delimiter=',')
|
||||
header = ['x', 'y','dx','dy', 'score', 'angle', 'type']
|
||||
csv_writer.writerow(header)
|
||||
for face in faces:
|
||||
csv_writer.writerow([str(i) for i in [int(face.x), int(face.y), int(face.dx), int(face.dy), face.score, face.angle, face.cascade_type]])
|
||||
return results_file
|
||||
|
||||
def get_sub_images_from_file(self,original_image_file, faces_file):
|
||||
'''
|
||||
extracts all the face sub-images from an image file, based on the results in a faces file
|
||||
|
||||
returns - the list of face images (numpy arrays)
|
||||
'''
|
||||
img = cv2.imread(original_image_file)
|
||||
faces_reader = csv.reader(open(faces_file))
|
||||
next(faces_reader) # discard the headings
|
||||
padded_face_images = []
|
||||
for line in faces_reader:
|
||||
x, y, dx, dy, score, angle, cascade_type = line
|
||||
[x,y,dx,dy,score, angle] = [int(float(i)) for i in [x,y,dx,dy,score, angle]]
|
||||
face = CascadeResult(([x,y,dx,dy], score), cascade_type, angle)
|
||||
padded_face, bounding_box_in_padded_face, _, _ = extract_box(img, face, padding_factor = 0.25)
|
||||
padded_face_images.append(padded_face)
|
||||
return padded_face_images
|
||||
|
||||
def create_sub_images_from_file(self, original_image_file, faces_file, target_folder = None, img_type = 'png'):
|
||||
'''
|
||||
reads a faces file, created by "self.create_faces_file" and extracts padded faces from the original image
|
||||
The faces will be created in the same folder as the faces file, unless specified otherwise by "target_folder"
|
||||
|
||||
returns - the list of face files (strings)
|
||||
'''
|
||||
target_folder = os.path.split(faces_file)[0] if target_folder is None else target_folder
|
||||
padded_face_images = self.get_sub_images_from_file(original_image_file, faces_file)
|
||||
|
||||
base_image_name = os.path.split(faces_file)[1].split('.')[0]
|
||||
face_files = []
|
||||
for n_face, face_img in enumerate(padded_face_images):
|
||||
face_file = os.path.join(target_folder, base_image_name + '_face_%d.%s' %(n_face, img_type))
|
||||
cv2.imwrite( face_file , face_img )
|
||||
face_files.append(face_file)
|
||||
return face_files
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
from adiencealign.common.images import extract_box
|
||||
import glob
|
||||
import os
|
||||
import time
|
||||
from adiencealign.cascade_detection.cascade_detector import CascadeDetector,\
|
||||
resolve_boxes, CascadeResult
|
||||
import cv2
|
||||
import csv
|
||||
'''
|
||||
Created on Dec 18, 2013
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
'''
|
||||
Created on Nov 26, 2013
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
|
||||
class CascadeFaceFinder(object):
|
||||
|
||||
def __init__(self,
|
||||
min_size = 32,
|
||||
drawn_target_res = 360*360,
|
||||
hangles = [0, -22, 22],
|
||||
langles = [0,-45,-22,22,45],
|
||||
haar_file = 'haarcascade_frontalface_default.xml',
|
||||
lbp_file = 'lbpcascade_frontalface.xml'):
|
||||
'''
|
||||
finder = CascadeFaceFinder(min_size = 32, drawn_target_res = 360*360, hangles = [0], langles = [0,-45,-22,22,45], parts_threshold = 0)
|
||||
|
||||
finder.get_faces_in_folder(input_folder, output_dir, drawn_folder, is_small_drawn)
|
||||
|
||||
or
|
||||
|
||||
finder.get_faces_in_photo(full_file, output_dir, drawn_folder, is_small_drawn)
|
||||
'''
|
||||
self.min_size = (min_size,min_size)
|
||||
self.drawn_target_res = drawn_target_res
|
||||
self._hangles = hangles
|
||||
self._langles = langles
|
||||
self.recalc_detectors(haar_file, lbp_file)
|
||||
|
||||
# self.funnel = FaceFunnel()
|
||||
|
||||
@property
|
||||
def hangles(self):
|
||||
return self._hangles
|
||||
|
||||
@hangles.setter
|
||||
def hangles(self,hangles):
|
||||
self._hangles = hangles
|
||||
self.recalc_detectors()
|
||||
|
||||
@property
|
||||
def langles(self):
|
||||
return self._langles
|
||||
|
||||
@langles.setter
|
||||
def langles(self,langles):
|
||||
self._langles = langles
|
||||
self.recalc_detectors()
|
||||
|
||||
def recalc_detectors(self, haar_file, lbp_file):
|
||||
self.haar_dtct = CascadeDetector(cascade_file = haar_file,
|
||||
min_size = self.min_size,
|
||||
min_neighbors = 20,
|
||||
scale_factor = 1.03,
|
||||
cascade_type = 'haar',
|
||||
thr = 0.4,
|
||||
angles = self.hangles)
|
||||
|
||||
self.lbp_dtct = CascadeDetector(cascade_file = lbp_file,
|
||||
min_size = self.min_size,
|
||||
min_neighbors = 15,
|
||||
scale_factor = 1.04,
|
||||
cascade_type = 'lbp',
|
||||
thr = 0.4,
|
||||
angles = self.langles)
|
||||
|
||||
|
||||
def get_faces_list_in_photo(self, img):
|
||||
if self.hangles:
|
||||
haar_faces = self.haar_dtct.detectWithAngles(img, resolve = True)
|
||||
else:
|
||||
haar_faces = []
|
||||
lbp_faces = self.lbp_dtct.detectWithAngles(img, resolve = True)
|
||||
faces = resolve_boxes({'haar':haar_faces, 'lbp':lbp_faces}, min_overlap = 0.6)
|
||||
|
||||
return faces
|
||||
|
||||
def create_faces_file(self, fname, is_overwrite = False, target_file = None):
|
||||
'''
|
||||
Runs facial detection on fname (say a.jpg, or a.png), and creates a results file (a.faces.txt)
|
||||
|
||||
target_file - override, and specify a specific target file
|
||||
is_overwrite - allow overwriting an existing results file
|
||||
'''
|
||||
faces = self.get_faces_list_in_photo(cv2.imread(fname))
|
||||
results_file = fname.rsplit('.',1)[0] + '.faces.txt' if target_file is None else target_file
|
||||
|
||||
if os.path.exists(results_file) and not is_overwrite:
|
||||
print "Warning, faces result file", results_file, "exists"
|
||||
else:
|
||||
with open(results_file,'w') as csvfile:
|
||||
csv_writer = csv.writer(csvfile, delimiter=',')
|
||||
header = ['x', 'y','dx','dy', 'score', 'angle', 'type']
|
||||
csv_writer.writerow(header)
|
||||
for face in faces:
|
||||
csv_writer.writerow([str(i) for i in [int(face.x), int(face.y), int(face.dx), int(face.dy), face.score, face.angle, face.cascade_type]])
|
||||
return results_file
|
||||
|
||||
def get_sub_images_from_file(self,original_image_file, faces_file):
|
||||
'''
|
||||
extracts all the face sub-images from an image file, based on the results in a faces file
|
||||
|
||||
returns - the list of face images (numpy arrays)
|
||||
'''
|
||||
img = cv2.imread(original_image_file)
|
||||
faces_reader = csv.reader(open(faces_file))
|
||||
faces_reader.next() # discard the headings
|
||||
padded_face_images = []
|
||||
for line in faces_reader:
|
||||
x, y, dx, dy, score, angle, cascade_type = line
|
||||
[x,y,dx,dy,score, angle] = [int(float(i)) for i in [x,y,dx,dy,score, angle]]
|
||||
face = CascadeResult(([x,y,dx,dy], score), cascade_type, angle)
|
||||
padded_face, bounding_box_in_padded_face, _, _ = extract_box(img, face, padding_factor = 0.25)
|
||||
padded_face_images.append(padded_face)
|
||||
return padded_face_images
|
||||
|
||||
def create_sub_images_from_file(self, original_image_file, faces_file, target_folder = None, img_type = 'png'):
|
||||
'''
|
||||
reads a faces file, created by "self.create_faces_file" and extracts padded faces from the original image
|
||||
The faces will be created in the same folder as the faces file, unless specified otherwise by "target_folder"
|
||||
|
||||
returns - the list of face files (strings)
|
||||
'''
|
||||
target_folder = os.path.split(faces_file)[0] if target_folder is None else target_folder
|
||||
padded_face_images = self.get_sub_images_from_file(original_image_file, faces_file)
|
||||
|
||||
base_image_name = os.path.split(faces_file)[1].split('.')[0]
|
||||
face_files = []
|
||||
for n_face, face_img in enumerate(padded_face_images):
|
||||
face_file = os.path.join(target_folder, base_image_name + '_face_%d.%s' %(n_face, img_type))
|
||||
cv2.imwrite( face_file , face_img )
|
||||
face_files.append(face_file)
|
||||
return face_files
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import cv2
|
||||
from adiencealign.cascade_detection.cascade_detector import CascadeResult
|
||||
import numpy as np
|
||||
|
||||
def draw_rect(img, r, angle = 0, color=(255,255,255), thickness = 4, alpha = 0.5):
|
||||
'''
|
||||
accepts:
|
||||
1. a (x,y,dx,dy) list
|
||||
4. a [(x,y,dx,dy),score] list, as returned by cv2.CascadeClassifier.detectMultiScaleWithScores()
|
||||
5. a CascadeResult object
|
||||
'''
|
||||
if type(r) == CascadeResult:
|
||||
color = tuple(list(color) + [alpha])
|
||||
cv2.polylines(img, pts = [r.points_int], isClosed = True, color = color, thickness = thickness)
|
||||
return
|
||||
elif len(r)==4 or len(r)==2: # [x,y,dx,dy]
|
||||
if len(r)==2:
|
||||
if len(r[0]) == 4:
|
||||
r = r[0]
|
||||
else:
|
||||
raise Exception("bad input to draw_rect...")
|
||||
pt1 = int(round(r[0])), int(round(r[1]))
|
||||
pt2 = int(round(r[0]+r[2])), int(round(r[1]+r[3]))
|
||||
color = tuple(list(color) + [alpha])
|
||||
cv2.rectangle(img, pt1, pt2, color, thickness = thickness)
|
||||
else:
|
||||
raise Exception("bad input to draw_rect...")
|
||||
return
|
|
@ -0,0 +1,22 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import os
|
||||
import shutil
|
||||
from os.path import expanduser
|
||||
|
||||
def make_path(path, delete_content_if_exists = False):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
elif delete_content_if_exists:
|
||||
shutil.rmtree(path)
|
||||
|
||||
def expand_path(file_or_path):
|
||||
if file_or_path.startswith('~/'):
|
||||
home = expanduser("~")
|
||||
file_at = os.path.join(home,file_or_path[2:])
|
||||
return file_at
|
||||
else:
|
||||
return file_or_path
|
|
@ -0,0 +1,87 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import math
|
||||
import numpy as np
|
||||
import cv2
|
||||
|
||||
|
||||
|
||||
def pad_image_for_rotation(img):
|
||||
# we pad the image so, when we rotate it, it would never be clipped
|
||||
rot_y,rot_x = img.shape[:2]
|
||||
rot_x = int(rot_x / 2.0)
|
||||
rot_y = int(rot_y / 2.0)
|
||||
diag = int(math.sqrt(sum([math.pow(x,2) for x in img.shape])))
|
||||
diag = int(math.ceil(diag / 2.0) * 2.0) # make sure it is even
|
||||
if len(img.shape) == 3:
|
||||
big_image = np.zeros((diag, diag, 3), dtype=np.uint8)
|
||||
else:
|
||||
big_image = np.zeros((diag, diag), dtype=np.uint8)
|
||||
x_shift = int(diag/2-rot_x)
|
||||
y_shift = int(diag/2-rot_y)
|
||||
# the shift of the old image within big_image
|
||||
if len(img.shape) == 3:
|
||||
big_image[y_shift :y_shift+img.shape[0], x_shift:x_shift+img.shape[1], :] = img
|
||||
else:
|
||||
big_image[y_shift :y_shift+img.shape[0], x_shift:x_shift+img.shape[1]] = img
|
||||
|
||||
# the rotation center is no the radius (half the old image diagonal)
|
||||
rot_center = diag/2, diag/2
|
||||
return big_image, x_shift, y_shift, diag, rot_center
|
||||
|
||||
|
||||
def extract_rect(img, rect, factor = 0.2):
|
||||
(x,y,dx,dy) = rect
|
||||
new_x = max(0, int(x-dx*factor))
|
||||
new_y = max(0, int(y-dy*factor))
|
||||
new_dx = min(int(dx+2*factor*dx), img.shape[1] - new_x)
|
||||
new_dy = min(int(dy+2*factor*dy), img.shape[0] - new_y)
|
||||
Dx = x - new_x
|
||||
Dy = y - new_y
|
||||
#return [new_x, new_y, new_dx, new_dy]
|
||||
return img[new_y:new_y+new_dy,new_x:new_x+new_dx,:], Dx, Dy
|
||||
|
||||
|
||||
def extract_box(img, box, padding_factor = 0.2):
|
||||
'''
|
||||
we can search for whatever we want in the rotated bordered image,
|
||||
|
||||
Any point found can be translated back to the original image by:
|
||||
1. adding the origins of the bordered area,
|
||||
2. rotating the point using the inverse rotation matrix
|
||||
|
||||
'''
|
||||
|
||||
if box.angle != 0:
|
||||
|
||||
b_w = max(img.shape)*2
|
||||
b_h = b_w
|
||||
dx_center = b_w / 2 - box.center[0]
|
||||
dy_center = b_h / 2 - box.center[1]
|
||||
new_img = np.zeros((b_w, b_h, 3), dtype = img.dtype)
|
||||
new_img[dy_center:(dy_center + img.shape[0]), dx_center:(dx_center + img.shape[1]), :] = img
|
||||
|
||||
box_in_big_image = box.points + np.c_[np.ones((4,1)) * dx_center, np.ones((4,1)) * dy_center]
|
||||
|
||||
rot_mat = cv2.getRotationMatrix2D((b_w/2, b_h/2), box.angle, scale = 1.0)
|
||||
inv_rot_mat = cv2.invertAffineTransform(rot_mat)
|
||||
rot_image = cv2.warpAffine(new_img, rot_mat, (new_img.shape[1],new_img.shape[0]), flags=cv2.INTER_CUBIC)
|
||||
box_UL_in_rotated = (rot_mat * np.matrix([box_in_big_image[0,0], box_in_big_image[0,1], 1]).transpose()).transpose().tolist()[0]
|
||||
box_coords_in_rotated = np.matrix(np.c_[box_in_big_image, np.ones((4,1))]) * rot_mat.T
|
||||
box_coords_in_rotated = box_coords_in_rotated[0,:].tolist()[0] + [box.dx, box.dy]
|
||||
else:
|
||||
rot_mat = cv2.getRotationMatrix2D(box.center, box.angle, scale = 1.0)
|
||||
inv_rot_mat = cv2.invertAffineTransform(rot_mat)
|
||||
# for efficiency
|
||||
rot_image = img.copy()
|
||||
box_UL_in_rotated = (rot_mat * np.matrix([box.points[0,0], box.points[0,1], 1]).transpose()).transpose().tolist()[0]
|
||||
box_coords_in_rotated = box_UL_in_rotated + [box.dx, box.dy]
|
||||
|
||||
img_with_border, Dx, Dy = extract_rect(rot_image, box_coords_in_rotated, padding_factor)
|
||||
box_coords_in_bordered = [Dx, Dy] + [box.dx, box.dy]
|
||||
border_UL_in_rotated = [box_UL_in_rotated[0]-Dx, box_UL_in_rotated[1]-Dy]
|
||||
|
||||
return img_with_border, box_coords_in_bordered, border_UL_in_rotated, inv_rot_mat
|
|
@ -0,0 +1,113 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
|
||||
import csv
|
||||
import cv2
|
||||
from numpy import linalg
|
||||
import numpy as np
|
||||
|
||||
|
||||
WEIGHTS3 = [11.1088851746,15.8721645013,12.3189439894,15.9467104922,13.9265119716,17.2447706133,11.4118267639,17.0728365324,12.7831886739,17.1908773151,9.6639887492,13.8443342456,8.76890470223,11.4441704453,7.52083144762,10.3245662427,6.35563072919,7.55739887985,6.42340544936,7.48786881875,10.8720924456,8.1349958353,12.3664410374,9.58137800608,6.29390307208,9.47697088783,8.49859202931,9.43946799727,7.92920023102,10.6126442536,10.2953809171,11.299323189,11.1181958685,12.9374719654,12.3764338392,14.7823225327,13.086272904,16.0571795811,15.079169884,17.5936174739,8.39112414861,7.68532826996,8.89386612449,8.70173923211,10.0826620269,8.70286074207,8.13121344224,9.80805203263,7.76044090777,9.2502084627,7.61334683331,10.4813589698,8.64831020289,11.0452512508,9.19528177019,13.0171747152,10.1204323102,14.0189765809,11.0232436734,14.7355286373,12.4881579947,15.4279914333,11.5785971474,16.7942051778,12.4916161829,17.57726411,14.3422306002,19.3015061859,16.3109851665,23.7227227093,17.7687071538,22.6848438204,14.9879312002,18.6763354368,12.927920123,17.7652660198,10.3584444834,15.5584775245,10.660322225,15.4351684107,11.6468441007,13.7962556973,12.9019472625,16.6407866045,13.1946878458,16.4137518526,9.86525395127,11.6687513083,10.4858060411,12.8407630953,9.24210197996,10.9728479778,9.37639005327,12.3418022852,12.2786533953,12.0629300205,14.8495857728,15.4667996708,14.7414922143,15.2761005039,8.5837102275,10.8010609515,6.55275411638,14.4240347981,10.4200283162,17.6888997346,11.4480670185,22.4669420211,13.1705102756,29.3073334802,16.9922725597,35.4031969543,18.7102372238,41.7466671473,21.7036998929,47.1495172267,24.4179633642,51.9023425203,26.6870471848,57.5921966087,7.71654443362,18.3796425232,9.84932443383,23.3915673615,15.7135746598,31.5768046636,18.159161567,39.0502675506,20.5154926286,44.6961338521,22.8541610324,50.9071591504,26.5569627651,54.4338495899,29.1062390164,61.5990210977]
|
||||
|
||||
def read_fidu(fidu_name):
|
||||
fidu_reader = csv.reader(open(fidu_name))
|
||||
try:
|
||||
line = next(fidu_reader)
|
||||
score, yaw_angle = line
|
||||
next(fidu_reader)
|
||||
fidu_points = [[int(float(field)) for field in row[-2:]] for row in fidu_reader]
|
||||
return int(score), int(yaw_angle), fidu_points
|
||||
except:
|
||||
if line[0] == 'nothing found':
|
||||
return -1000, None, None
|
||||
else:
|
||||
raise Exception('Corrupt Fidu File ' + fidu_name)
|
||||
|
||||
|
||||
def draw_fidu(img, fidu_points, radius = 3, color = (255,0,0), thickness = 1, draw_numbers_color = None):
|
||||
'''
|
||||
set draw_numbers_color = (COLOR_BLUE), for example, to draw the point numbers
|
||||
'''
|
||||
for n,point in enumerate(fidu_points):
|
||||
cv2.circle(img, tuple([int(x) for x in point]),radius,color, thickness)
|
||||
if draw_numbers_color:
|
||||
cv2.putText( img,
|
||||
'%d' %n,
|
||||
tuple([int(point[0])-4, int(point[1])-4]),
|
||||
cv2.FONT_HERSHEY_COMPLEX,
|
||||
0.35,
|
||||
draw_numbers_color,
|
||||
thickness = 1 )
|
||||
|
||||
|
||||
|
||||
def _compute_affine_transform_cvpy(refpoints, points, w = None): # Copied from the book
|
||||
if w == None:
|
||||
w = [1] * (len(points) * 2)
|
||||
assert(len(w) == 2*len(points))
|
||||
y = []
|
||||
for n, p in enumerate(refpoints):
|
||||
y += [p[0]/w[n*2], p[1]/w[n*2+1]]
|
||||
A = []
|
||||
for n, p in enumerate(points):
|
||||
A.extend([ [p[0]/w[n*2], p[1]/w[n*2], 0, 0, 1/w[n*2], 0], [0, 0, p[0]/w[n*2+1], p[1]/w[n*2+1], 0, 1/w[n*2+1]] ])
|
||||
|
||||
lstsq = linalg.lstsq(A,y)
|
||||
h11, h12, h21, h22, dx, dy = lstsq[0]
|
||||
err = lstsq[1]
|
||||
|
||||
R = np.array([[h11, h12, dx], [h21, h22, dy]])
|
||||
return R, err
|
||||
|
||||
|
||||
def _compute_affine_transform_ocvlsq(refpoints, points, w = None):
|
||||
if w == None:
|
||||
w = [1] * (len(points) * 2)
|
||||
assert(len(w) == 2*len(points))
|
||||
y = []
|
||||
for n, p in enumerate(refpoints):
|
||||
y += [p[0]/w[n*2], p[1]/w[n*2+1]]
|
||||
A = []
|
||||
for n, p in enumerate(points):
|
||||
A.extend([ [p[0]/w[n*2], p[1]/w[n*2], 0, 0, 1/w[n*2], 0], [0, 0, p[0]/w[n*2+1], p[1]/w[n*2+1], 0, 1/w[n*2+1]] ])
|
||||
|
||||
lstsq = cv2.solve(np.array(A), np.array(y), flags=cv2.DECOMP_SVD)
|
||||
h11, h12, h21, h22, dx, dy = lstsq[1]
|
||||
err = 0#lstsq[1]
|
||||
|
||||
#R = np.array([[h11, h12, dx], [h21, h22, dy]])
|
||||
# The row above works too - but creates a redundant dimension
|
||||
R = np.array([[h11[0], h12[0], dx[0]], [h21[0], h22[0], dy[0]]])
|
||||
return R, err
|
||||
|
||||
def fidu_transform(fidu_model, fidu_points, weights, img, shift=(0.0,0.0), use_ocvlsq=False):
|
||||
FIDU_SIZE = 544
|
||||
|
||||
SHIFT_Y = int(FIDU_SIZE * shift[0])
|
||||
SHIFT_X = int(FIDU_SIZE * shift[1])
|
||||
if not use_ocvlsq:
|
||||
R, err = _compute_affine_transform_cvpy(fidu_model, fidu_points, weights)
|
||||
else:
|
||||
R, err = _compute_affine_transform_ocvlsq(fidu_model, fidu_points, weights)
|
||||
|
||||
funneled_img = cv2.warpAffine(img, R, (FIDU_SIZE + SHIFT_Y*2, FIDU_SIZE + SHIFT_X*2), flags=cv2.INTER_CUBIC)
|
||||
return funneled_img, R
|
||||
|
||||
|
||||
def shift_vector(points, shift):
|
||||
FIDU_SIZE = 544
|
||||
|
||||
SHIFT_Y = int(FIDU_SIZE * shift[0])
|
||||
SHIFT_X = int(FIDU_SIZE * shift[1])
|
||||
SHIFT = (SHIFT_X, SHIFT_Y)
|
||||
s_points = [(p[0] + SHIFT[0], p[1] + SHIFT[1]) for p in points]
|
||||
return s_points
|
||||
|
||||
def unwarp_fidu(orig_fidu_points, unwarp_mat):
|
||||
points = np.array(orig_fidu_points).T
|
||||
points_h = np.r_[points, np.ones((1,points.shape[1]))]
|
||||
orig_fidu_points_in_aligned = np.dot(unwarp_mat,points_h).T.astype(np.int16)
|
||||
return orig_fidu_points_in_aligned
|
|
@ -0,0 +1,113 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
|
||||
import csv
|
||||
import cv2
|
||||
from numpy import linalg
|
||||
import numpy as np
|
||||
|
||||
|
||||
WEIGHTS3 = [11.1088851746,15.8721645013,12.3189439894,15.9467104922,13.9265119716,17.2447706133,11.4118267639,17.0728365324,12.7831886739,17.1908773151,9.6639887492,13.8443342456,8.76890470223,11.4441704453,7.52083144762,10.3245662427,6.35563072919,7.55739887985,6.42340544936,7.48786881875,10.8720924456,8.1349958353,12.3664410374,9.58137800608,6.29390307208,9.47697088783,8.49859202931,9.43946799727,7.92920023102,10.6126442536,10.2953809171,11.299323189,11.1181958685,12.9374719654,12.3764338392,14.7823225327,13.086272904,16.0571795811,15.079169884,17.5936174739,8.39112414861,7.68532826996,8.89386612449,8.70173923211,10.0826620269,8.70286074207,8.13121344224,9.80805203263,7.76044090777,9.2502084627,7.61334683331,10.4813589698,8.64831020289,11.0452512508,9.19528177019,13.0171747152,10.1204323102,14.0189765809,11.0232436734,14.7355286373,12.4881579947,15.4279914333,11.5785971474,16.7942051778,12.4916161829,17.57726411,14.3422306002,19.3015061859,16.3109851665,23.7227227093,17.7687071538,22.6848438204,14.9879312002,18.6763354368,12.927920123,17.7652660198,10.3584444834,15.5584775245,10.660322225,15.4351684107,11.6468441007,13.7962556973,12.9019472625,16.6407866045,13.1946878458,16.4137518526,9.86525395127,11.6687513083,10.4858060411,12.8407630953,9.24210197996,10.9728479778,9.37639005327,12.3418022852,12.2786533953,12.0629300205,14.8495857728,15.4667996708,14.7414922143,15.2761005039,8.5837102275,10.8010609515,6.55275411638,14.4240347981,10.4200283162,17.6888997346,11.4480670185,22.4669420211,13.1705102756,29.3073334802,16.9922725597,35.4031969543,18.7102372238,41.7466671473,21.7036998929,47.1495172267,24.4179633642,51.9023425203,26.6870471848,57.5921966087,7.71654443362,18.3796425232,9.84932443383,23.3915673615,15.7135746598,31.5768046636,18.159161567,39.0502675506,20.5154926286,44.6961338521,22.8541610324,50.9071591504,26.5569627651,54.4338495899,29.1062390164,61.5990210977]
|
||||
|
||||
def read_fidu(fidu_name):
|
||||
fidu_reader = csv.reader(open(fidu_name))
|
||||
try:
|
||||
line = fidu_reader.next()
|
||||
score, yaw_angle = line
|
||||
fidu_reader.next()
|
||||
fidu_points = [[int(float(field)) for field in row[-2:]] for row in fidu_reader]
|
||||
return int(score), int(yaw_angle), fidu_points
|
||||
except:
|
||||
if line[0] == 'nothing found':
|
||||
return -1000, None, None
|
||||
else:
|
||||
raise Exception('Corrupt Fidu File ' + fidu_name)
|
||||
|
||||
|
||||
def draw_fidu(img, fidu_points, radius = 3, color = (255,0,0), thickness = 1, draw_numbers_color = None):
|
||||
'''
|
||||
set draw_numbers_color = (COLOR_BLUE), for example, to draw the point numbers
|
||||
'''
|
||||
for n,point in enumerate(fidu_points):
|
||||
cv2.circle(img, tuple([int(x) for x in point]),radius,color, thickness)
|
||||
if draw_numbers_color:
|
||||
cv2.putText( img,
|
||||
'%d' %n,
|
||||
tuple([int(point[0])-4, int(point[1])-4]),
|
||||
cv2.FONT_HERSHEY_COMPLEX,
|
||||
0.35,
|
||||
draw_numbers_color,
|
||||
thickness = 1 )
|
||||
|
||||
|
||||
|
||||
def _compute_affine_transform_cvpy(refpoints, points, w = None): # Copied from the book
|
||||
if w == None:
|
||||
w = [1] * (len(points) * 2)
|
||||
assert(len(w) == 2*len(points))
|
||||
y = []
|
||||
for n, p in enumerate(refpoints):
|
||||
y += [p[0]/w[n*2], p[1]/w[n*2+1]]
|
||||
A = []
|
||||
for n, p in enumerate(points):
|
||||
A.extend([ [p[0]/w[n*2], p[1]/w[n*2], 0, 0, 1/w[n*2], 0], [0, 0, p[0]/w[n*2+1], p[1]/w[n*2+1], 0, 1/w[n*2+1]] ])
|
||||
|
||||
lstsq = linalg.lstsq(A,y)
|
||||
h11, h12, h21, h22, dx, dy = lstsq[0]
|
||||
err = lstsq[1]
|
||||
|
||||
R = np.array([[h11, h12, dx], [h21, h22, dy]])
|
||||
return R, err
|
||||
|
||||
|
||||
def _compute_affine_transform_ocvlsq(refpoints, points, w = None):
|
||||
if w == None:
|
||||
w = [1] * (len(points) * 2)
|
||||
assert(len(w) == 2*len(points))
|
||||
y = []
|
||||
for n, p in enumerate(refpoints):
|
||||
y += [p[0]/w[n*2], p[1]/w[n*2+1]]
|
||||
A = []
|
||||
for n, p in enumerate(points):
|
||||
A.extend([ [p[0]/w[n*2], p[1]/w[n*2], 0, 0, 1/w[n*2], 0], [0, 0, p[0]/w[n*2+1], p[1]/w[n*2+1], 0, 1/w[n*2+1]] ])
|
||||
|
||||
lstsq = cv2.solve(np.array(A), np.array(y), flags=cv2.DECOMP_SVD)
|
||||
h11, h12, h21, h22, dx, dy = lstsq[1]
|
||||
err = 0#lstsq[1]
|
||||
|
||||
#R = np.array([[h11, h12, dx], [h21, h22, dy]])
|
||||
# The row above works too - but creates a redundant dimension
|
||||
R = np.array([[h11[0], h12[0], dx[0]], [h21[0], h22[0], dy[0]]])
|
||||
return R, err
|
||||
|
||||
def fidu_transform(fidu_model, fidu_points, weights, img, shift=(0.0,0.0), use_ocvlsq=False):
|
||||
FIDU_SIZE = 544
|
||||
|
||||
SHIFT_Y = int(FIDU_SIZE * shift[0])
|
||||
SHIFT_X = int(FIDU_SIZE * shift[1])
|
||||
if not use_ocvlsq:
|
||||
R, err = _compute_affine_transform_cvpy(fidu_model, fidu_points, weights)
|
||||
else:
|
||||
R, err = _compute_affine_transform_ocvlsq(fidu_model, fidu_points, weights)
|
||||
|
||||
funneled_img = cv2.warpAffine(img, R, (FIDU_SIZE + SHIFT_Y*2, FIDU_SIZE + SHIFT_X*2), flags=cv2.INTER_CUBIC)
|
||||
return funneled_img, R
|
||||
|
||||
|
||||
def shift_vector(points, shift):
|
||||
FIDU_SIZE = 544
|
||||
|
||||
SHIFT_Y = int(FIDU_SIZE * shift[0])
|
||||
SHIFT_X = int(FIDU_SIZE * shift[1])
|
||||
SHIFT = (SHIFT_X, SHIFT_Y)
|
||||
s_points = [(p[0] + SHIFT[0], p[1] + SHIFT[1]) for p in points]
|
||||
return s_points
|
||||
|
||||
def unwarp_fidu(orig_fidu_points, unwarp_mat):
|
||||
points = np.array(orig_fidu_points).T
|
||||
points_h = np.r_[points, np.ones((1,points.shape[1]))]
|
||||
orig_fidu_points_in_aligned = np.dot(unwarp_mat,points_h).T.astype(np.int16)
|
||||
return orig_fidu_points_in_aligned
|
|
@ -0,0 +1,20 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
def detect_landmarks(fname, max_size = 400*400, min_size = 50*50, fidu_exec_dir = os.path.abspath('../resources/')):
|
||||
'''
|
||||
optional flags:
|
||||
max_size - If exceeds this pixel size, image is resized to that before landmark detection
|
||||
min_size - If below this pixel size, image is resized to that before landmark detection
|
||||
'''
|
||||
max_size = str(max_size) if max_size is not None else ''
|
||||
min_size = str(min_size) if min_size is not None else ''
|
||||
fidu_cmd = './FiducialFaceDetector.sh Face_small_146filters_-0.65thr.xml %s %s %s' %(fname, min_size, max_size)
|
||||
print(fidu_cmd)
|
||||
x = subprocess.call(fidu_cmd, shell=True, cwd = fidu_exec_dir)
|
||||
return
|
|
@ -0,0 +1,20 @@
|
|||
'''
|
||||
Created on May 7, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
def detect_landmarks(fname, max_size = 400*400, min_size = 50*50, fidu_exec_dir = os.path.abspath('../resources/')):
|
||||
'''
|
||||
optional flags:
|
||||
max_size - If exceeds this pixel size, image is resized to that before landmark detection
|
||||
min_size - If below this pixel size, image is resized to that before landmark detection
|
||||
'''
|
||||
max_size = str(max_size) if max_size is not None else ''
|
||||
min_size = str(min_size) if min_size is not None else ''
|
||||
fidu_cmd = './FiducialFaceDetector.sh Face_small_146filters_-0.65thr.xml %s %s %s' %(fname, min_size, max_size)
|
||||
print fidu_cmd
|
||||
x = subprocess.call(fidu_cmd, shell=True, cwd = fidu_exec_dir)
|
||||
return
|
|
@ -0,0 +1,148 @@
|
|||
'''
|
||||
Created on May 8, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
from adiencealign.cascade_detection.cascade_face_finder import CascadeFaceFinder
|
||||
from adiencealign.affine_alignment.affine_aligner import AffineAligner
|
||||
import glob
|
||||
import os
|
||||
from adiencealign.landmarks_detection.landmarks_detector import detect_landmarks
|
||||
from adiencealign.common.landmarks import read_fidu, unwarp_fidu, draw_fidu
|
||||
import cv2
|
||||
|
||||
class CascadeFaceAligner(object):
|
||||
'''
|
||||
classdocs
|
||||
'''
|
||||
|
||||
|
||||
def __init__(self, haar_file = '../resources/haarcascade_frontalface_default.xml',
|
||||
lbp_file = '../resources/lbpcascade_frontalface.xml',
|
||||
fidu_model_file = '../resources/model_ang_0.txt',
|
||||
fidu_exec_dir = '../resources/'):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
self.face_finder = CascadeFaceFinder(haar_file = haar_file,
|
||||
lbp_file = lbp_file)
|
||||
|
||||
self.aligner = AffineAligner(fidu_model_file = fidu_model_file)
|
||||
self.fidu_exec_dir = fidu_exec_dir
|
||||
|
||||
self.valid_angles = [-45,-30,-15,0,15,30,45]
|
||||
|
||||
def detect_faces(self, input_folder, output_folder, mark_dones = True):
|
||||
'''
|
||||
mark_dones - if True, will create a hidden file, marking this file as done with a hidden file, starting with '.done.'
|
||||
'''
|
||||
input_files1 = glob.glob(os.path.join(input_folder, '*.jpg'))
|
||||
input_files2 = glob.glob(os.path.join(input_folder, '*.png'))
|
||||
input_files = input_files1 + input_files2
|
||||
N = len(input_files)
|
||||
|
||||
for n_file, input_file in enumerate(input_files):
|
||||
a,b = os.path.split(input_file)
|
||||
done_file = os.path.join(a, '.done.' + b.rsplit('.',1)[0])
|
||||
|
||||
if os.path.exists(done_file):
|
||||
continue
|
||||
|
||||
print("... processing", input_file)
|
||||
|
||||
target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt')
|
||||
|
||||
faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file )
|
||||
sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file,
|
||||
faces_file = faces_file,
|
||||
target_folder = output_folder,
|
||||
img_type = 'jpg')
|
||||
#touch
|
||||
open(done_file,'w').close()
|
||||
print("Detected on %d / %d files" %(n_file, N))
|
||||
|
||||
def align_faces(self, input_images, output_path, fidu_max_size = None, fidu_min_size = None, is_align = True, is_draw_fidu = False, delete_no_fidu = False):
|
||||
'''
|
||||
input_images - can be either a folder (all *.jpgs in it) or a list of filenames
|
||||
|
||||
, fidu_max_size = None, fidu_min_size = None):
|
||||
'''
|
||||
if type(input_images) == type(''):
|
||||
input_images = glob.glob(os.path.join(input_images, '*.jpg'))
|
||||
|
||||
for input_image in input_images:
|
||||
detect_landmarks(fname = os.path.abspath(input_image),
|
||||
max_size = fidu_max_size,
|
||||
min_size = fidu_min_size,
|
||||
fidu_exec_dir = self.fidu_exec_dir)
|
||||
|
||||
fidu_file = input_image.rsplit('.',1)[0] + '.cfidu'
|
||||
fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file)
|
||||
|
||||
if not (fidu_score is not None and yaw_angle in self.valid_angles):
|
||||
# skip face
|
||||
if delete_no_fidu:
|
||||
os.remove(fidu_file)
|
||||
os.remove(input_image)
|
||||
continue
|
||||
|
||||
if is_align:
|
||||
# save the aligned image
|
||||
sub_img = cv2.imread(input_image)
|
||||
_, base_fname = os.path.split(input_image)
|
||||
aligned_img, R = self.aligner.align(sub_img, fidu_points)
|
||||
aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.png')
|
||||
cv2.imwrite(aligned_img_file, aligned_img)
|
||||
|
||||
# save a copy of the aligned image, with the landmarks drawn
|
||||
if is_draw_fidu:
|
||||
aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.withpoints.png')
|
||||
fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R)
|
||||
draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3)
|
||||
cv2.imwrite(aligned_img_file, aligned_img)
|
||||
|
||||
#
|
||||
# def align_faces2(self, input_folder, output_folder, detect_landmarks = True, delete_no_fidu = True, is_align = True, is_draw_fidu = False, fidu_max_size = None, fidu_min_size = None):
|
||||
# '''
|
||||
# delete_no_fidu - deletes the .cfidu and sub_img if no fidu was found
|
||||
# is_draw_fidu - creates a copy of the aligned images with the original fiducial points on it
|
||||
# '''
|
||||
# input_files = glob.glob(os.path.join(input_folder, '*'))
|
||||
# for input_file in input_files:
|
||||
# print "... processing", input_file
|
||||
# target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt')
|
||||
#
|
||||
# faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file )
|
||||
# sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file,
|
||||
# faces_file = faces_file,
|
||||
# target_folder = output_folder,
|
||||
# img_type = 'jpg')
|
||||
#
|
||||
# for sub_image_file in sub_images_files:
|
||||
# detect_landmarks(fname = os.path.abspath(sub_image_file),
|
||||
# max_size = fidu_max_size,
|
||||
# min_size = fidu_min_size,
|
||||
# fidu_exec_dir = self.fidu_exec_dir)
|
||||
#
|
||||
# fidu_file = sub_image_file.rsplit('.',1)[0] + '.cfidu'
|
||||
# fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file)
|
||||
#
|
||||
# if not (fidu_score is not None and yaw_angle in self.valid_angles):
|
||||
# # skip face
|
||||
# os.remove(fidu_file)
|
||||
# os.remove(sub_image_file)
|
||||
# continue
|
||||
#
|
||||
# if is_align:
|
||||
# # save the aligned image
|
||||
# sub_img = cv2.imread(sub_image_file)
|
||||
# aligned_img, R = self.aligner.align(sub_img, fidu_points)
|
||||
# aligned_img_file = sub_image_file.rsplit('.',1)[0] + '.aligned.png'
|
||||
# cv2.imwrite(aligned_img_file, aligned_img)
|
||||
#
|
||||
# # save a copy of the aligned image, with the landmarks drawn
|
||||
# if is_draw_fidu:
|
||||
# aligned_img_file = sub_image_file.rsplit('.',1)[0] + '.aligned.withpoints.png'
|
||||
# fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R)
|
||||
# draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3)
|
||||
# cv2.imwrite(aligned_img_file, aligned_img)
|
|
@ -0,0 +1,148 @@
|
|||
'''
|
||||
Created on May 8, 2014
|
||||
|
||||
@author: eran
|
||||
'''
|
||||
from adiencealign.cascade_detection.cascade_face_finder import CascadeFaceFinder
|
||||
from adiencealign.affine_alignment.affine_aligner import AffineAligner
|
||||
import glob
|
||||
import os
|
||||
from adiencealign.landmarks_detection.landmarks_detector import detect_landmarks
|
||||
from adiencealign.common.landmarks import read_fidu, unwarp_fidu, draw_fidu
|
||||
import cv2
|
||||
|
||||
class CascadeFaceAligner(object):
|
||||
'''
|
||||
classdocs
|
||||
'''
|
||||
|
||||
|
||||
def __init__(self, haar_file = '../resources/haarcascade_frontalface_default.xml',
|
||||
lbp_file = '../resources/lbpcascade_frontalface.xml',
|
||||
fidu_model_file = '../resources/model_ang_0.txt',
|
||||
fidu_exec_dir = '../resources/'):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
self.face_finder = CascadeFaceFinder(haar_file = haar_file,
|
||||
lbp_file = lbp_file)
|
||||
|
||||
self.aligner = AffineAligner(fidu_model_file = fidu_model_file)
|
||||
self.fidu_exec_dir = fidu_exec_dir
|
||||
|
||||
self.valid_angles = [-45,-30,-15,0,15,30,45]
|
||||
|
||||
def detect_faces(self, input_folder, output_folder, mark_dones = True):
|
||||
'''
|
||||
mark_dones - if True, will create a hidden file, marking this file as done with a hidden file, starting with '.done.'
|
||||
'''
|
||||
input_files1 = glob.glob(os.path.join(input_folder, '*.jpg'))
|
||||
input_files2 = glob.glob(os.path.join(input_folder, '*.png'))
|
||||
input_files = input_files1 + input_files2
|
||||
N = len(input_files)
|
||||
|
||||
for n_file, input_file in enumerate(input_files):
|
||||
a,b = os.path.split(input_file)
|
||||
done_file = os.path.join(a, '.done.' + b.rsplit('.',1)[0])
|
||||
|
||||
if os.path.exists(done_file):
|
||||
continue
|
||||
|
||||
print "... processing", input_file
|
||||
|
||||
target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt')
|
||||
|
||||
faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file )
|
||||
sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file,
|
||||
faces_file = faces_file,
|
||||
target_folder = output_folder,
|
||||
img_type = 'jpg')
|
||||
#touch
|
||||
open(done_file,'w').close()
|
||||
print "Detected on %d / %d files" %(n_file, N)
|
||||
|
||||
def align_faces(self, input_images, output_path, fidu_max_size = None, fidu_min_size = None, is_align = True, is_draw_fidu = False, delete_no_fidu = False):
|
||||
'''
|
||||
input_images - can be either a folder (all *.jpgs in it) or a list of filenames
|
||||
|
||||
, fidu_max_size = None, fidu_min_size = None):
|
||||
'''
|
||||
if type(input_images) == type(''):
|
||||
input_images = glob.glob(os.path.join(input_images, '*.jpg'))
|
||||
|
||||
for input_image in input_images:
|
||||
detect_landmarks(fname = os.path.abspath(input_image),
|
||||
max_size = fidu_max_size,
|
||||
min_size = fidu_min_size,
|
||||
fidu_exec_dir = self.fidu_exec_dir)
|
||||
|
||||
fidu_file = input_image.rsplit('.',1)[0] + '.cfidu'
|
||||
fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file)
|
||||
|
||||
if not (fidu_score is not None and yaw_angle in self.valid_angles):
|
||||
# skip face
|
||||
if delete_no_fidu:
|
||||
os.remove(fidu_file)
|
||||
os.remove(input_image)
|
||||
continue
|
||||
|
||||
if is_align:
|
||||
# save the aligned image
|
||||
sub_img = cv2.imread(input_image)
|
||||
_, base_fname = os.path.split(input_image)
|
||||
aligned_img, R = self.aligner.align(sub_img, fidu_points)
|
||||
aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.png')
|
||||
cv2.imwrite(aligned_img_file, aligned_img)
|
||||
|
||||
# save a copy of the aligned image, with the landmarks drawn
|
||||
if is_draw_fidu:
|
||||
aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.withpoints.png')
|
||||
fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R)
|
||||
draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3)
|
||||
cv2.imwrite(aligned_img_file, aligned_img)
|
||||
|
||||
#
|
||||
# def align_faces2(self, input_folder, output_folder, detect_landmarks = True, delete_no_fidu = True, is_align = True, is_draw_fidu = False, fidu_max_size = None, fidu_min_size = None):
|
||||
# '''
|
||||
# delete_no_fidu - deletes the .cfidu and sub_img if no fidu was found
|
||||
# is_draw_fidu - creates a copy of the aligned images with the original fiducial points on it
|
||||
# '''
|
||||
# input_files = glob.glob(os.path.join(input_folder, '*'))
|
||||
# for input_file in input_files:
|
||||
# print "... processing", input_file
|
||||
# target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt')
|
||||
#
|
||||
# faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file )
|
||||
# sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file,
|
||||
# faces_file = faces_file,
|
||||
# target_folder = output_folder,
|
||||
# img_type = 'jpg')
|
||||
#
|
||||
# for sub_image_file in sub_images_files:
|
||||
# detect_landmarks(fname = os.path.abspath(sub_image_file),
|
||||
# max_size = fidu_max_size,
|
||||
# min_size = fidu_min_size,
|
||||
# fidu_exec_dir = self.fidu_exec_dir)
|
||||
#
|
||||
# fidu_file = sub_image_file.rsplit('.',1)[0] + '.cfidu'
|
||||
# fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file)
|
||||
#
|
||||
# if not (fidu_score is not None and yaw_angle in self.valid_angles):
|
||||
# # skip face
|
||||
# os.remove(fidu_file)
|
||||
# os.remove(sub_image_file)
|
||||
# continue
|
||||
#
|
||||
# if is_align:
|
||||
# # save the aligned image
|
||||
# sub_img = cv2.imread(sub_image_file)
|
||||
# aligned_img, R = self.aligner.align(sub_img, fidu_points)
|
||||
# aligned_img_file = sub_image_file.rsplit('.',1)[0] + '.aligned.png'
|
||||
# cv2.imwrite(aligned_img_file, aligned_img)
|
||||
#
|
||||
# # save a copy of the aligned image, with the landmarks drawn
|
||||
# if is_draw_fidu:
|
||||
# aligned_img_file = sub_image_file.rsplit('.',1)[0] + '.aligned.withpoints.png'
|
||||
# fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R)
|
||||
# draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3)
|
||||
# cv2.imwrite(aligned_img_file, aligned_img)
|
65460
adience_align-master/adiencealign(old)/resources/Face_small_146filters_-0.65thr.xml
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:.
|
||||
"./FiducialFaceDetector" $1 $2 $3 $4
|
|
@ -0,0 +1,68 @@
|
|||
1,272,272
|
||||
2,252,272
|
||||
3,232,272
|
||||
4,292,272
|
||||
5,312,272
|
||||
6,272,232
|
||||
7,272,192
|
||||
8,272,152
|
||||
9,272,112
|
||||
10,212,112
|
||||
11,192,112
|
||||
12,172,112
|
||||
13,192,92
|
||||
14,172,92
|
||||
15,152,112
|
||||
16,112,72
|
||||
17,132,52
|
||||
18,172,52
|
||||
19,212,52
|
||||
20,252,52
|
||||
21,332,112
|
||||
22,352,112
|
||||
23,372,112
|
||||
24,352,92
|
||||
25,372,92
|
||||
26,392,112
|
||||
27,432,72
|
||||
28,412,52
|
||||
29,372,52
|
||||
30,332,52
|
||||
31,292,52
|
||||
32,272,312
|
||||
33,252,312
|
||||
34,232,332
|
||||
35,212,352
|
||||
36,232,352
|
||||
37,252,332
|
||||
38,272,332
|
||||
39,312,312
|
||||
40,332,332
|
||||
41,352,352
|
||||
42,332,352
|
||||
43,312,332
|
||||
44,332,372
|
||||
45,312,352
|
||||
46,312,372
|
||||
47,272,352
|
||||
48,252,372
|
||||
49,252,352
|
||||
50,232,372
|
||||
51,272,372
|
||||
52,272,492
|
||||
53,212,492
|
||||
54,172,472
|
||||
55,132,432
|
||||
56,92,392
|
||||
57,72,332
|
||||
58,52,272
|
||||
59,52,212
|
||||
60,52,152
|
||||
61,332,472
|
||||
62,372,452
|
||||
63,412,412
|
||||
64,452,372
|
||||
65,472,312
|
||||
66,472,252
|
||||
67,472,192
|
||||
68,472,132
|
After Width: | Height: | Size: 696 KiB |
|
@ -0,0 +1,6 @@
|
|||
rm outputs/pipeline/faces/*
|
||||
rm outputs/pipeline/aligned/*
|
||||
rm outputs/cascade/1/*
|
||||
rm outputs/cascade/2/*
|
||||
|
||||
rm resources/pipeline/.done*
|
|
@ -0,0 +1,4 @@
|
|||
rm outputs/pipeline/faces/*
|
||||
rm outputs/pipeline/aligned/*
|
||||
rm outputs/cascade/1/*
|
||||
rm outputs/cascade/2/*
|
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 44 KiB |
|
@ -0,0 +1,2 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
61,62,132,132,344,0.0,haar
|
After Width: | Height: | Size: 61 KiB |
|
@ -0,0 +1,5 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
327,101,121,121,154,0.0,lbp
|
||||
237,106,113,113,139,0.0,lbp
|
||||
164,49,91,91,49,0.0,lbp
|
||||
434,86,94,94,95,0.0,lbp
|
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 436 KiB |
After Width: | Height: | Size: 449 KiB |
After Width: | Height: | Size: 696 KiB |
After Width: | Height: | Size: 703 KiB |
After Width: | Height: | Size: 645 KiB |
After Width: | Height: | Size: 649 KiB |
After Width: | Height: | Size: 586 KiB |
After Width: | Height: | Size: 586 KiB |
After Width: | Height: | Size: 720 KiB |
After Width: | Height: | Size: 722 KiB |
After Width: | Height: | Size: 742 KiB |
After Width: | Height: | Size: 741 KiB |
After Width: | Height: | Size: 750 KiB |
After Width: | Height: | Size: 750 KiB |
After Width: | Height: | Size: 783 KiB |
After Width: | Height: | Size: 781 KiB |
After Width: | Height: | Size: 696 KiB |
After Width: | Height: | Size: 696 KiB |
|
@ -0,0 +1,2 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
61,62,132,132,344,0.0,haar
|
|
@ -0,0 +1,70 @@
|
|||
233,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
87.00,106.00,22.00,22.00,98.00,117.00
|
||||
83.00,106.00,22.00,22.00,94.00,117.00
|
||||
78.00,106.00,22.00,22.00,89.00,117.00
|
||||
92.00,106.00,22.00,22.00,103.00,117.00
|
||||
96.00,106.00,22.00,22.00,107.00,117.00
|
||||
87.00,96.00,22.00,22.00,98.00,107.00
|
||||
87.00,87.00,22.00,22.00,98.00,98.00
|
||||
87.00,78.00,22.00,22.00,98.00,89.00
|
||||
87.00,74.00,22.00,22.00,98.00,85.00
|
||||
74.00,74.00,22.00,22.00,85.00,85.00
|
||||
69.00,74.00,22.00,22.00,80.00,85.00
|
||||
64.00,74.00,22.00,22.00,75.00,85.00
|
||||
69.00,69.00,22.00,22.00,80.00,80.00
|
||||
64.00,69.00,22.00,22.00,75.00,80.00
|
||||
60.00,74.00,22.00,22.00,71.00,85.00
|
||||
51.00,64.00,22.00,22.00,62.00,75.00
|
||||
55.00,55.00,22.00,22.00,66.00,66.00
|
||||
60.00,51.00,22.00,22.00,71.00,62.00
|
||||
69.00,55.00,22.00,22.00,80.00,66.00
|
||||
74.00,60.00,22.00,22.00,85.00,71.00
|
||||
96.00,74.00,22.00,22.00,107.00,85.00
|
||||
101.00,74.00,22.00,22.00,112.00,85.00
|
||||
106.00,74.00,22.00,22.00,117.00,85.00
|
||||
101.00,69.00,22.00,22.00,112.00,80.00
|
||||
106.00,69.00,22.00,22.00,117.00,80.00
|
||||
110.00,74.00,22.00,22.00,121.00,85.00
|
||||
119.00,64.00,22.00,22.00,130.00,75.00
|
||||
115.00,60.00,22.00,22.00,126.00,71.00
|
||||
106.00,55.00,22.00,22.00,117.00,66.00
|
||||
101.00,55.00,22.00,22.00,112.00,66.00
|
||||
92.00,55.00,22.00,22.00,103.00,66.00
|
||||
87.00,110.00,22.00,22.00,98.00,121.00
|
||||
78.00,110.00,22.00,22.00,89.00,121.00
|
||||
74.00,115.00,22.00,22.00,85.00,126.00
|
||||
69.00,119.00,22.00,22.00,80.00,130.00
|
||||
69.00,119.00,22.00,22.00,80.00,130.00
|
||||
78.00,115.00,22.00,22.00,89.00,126.00
|
||||
87.00,115.00,22.00,22.00,98.00,126.00
|
||||
96.00,110.00,22.00,22.00,107.00,121.00
|
||||
101.00,115.00,22.00,22.00,112.00,126.00
|
||||
106.00,119.00,22.00,22.00,117.00,130.00
|
||||
101.00,115.00,22.00,22.00,112.00,126.00
|
||||
101.00,115.00,22.00,22.00,112.00,126.00
|
||||
101.00,124.00,22.00,22.00,112.00,135.00
|
||||
96.00,119.00,22.00,22.00,107.00,130.00
|
||||
96.00,129.00,22.00,22.00,107.00,140.00
|
||||
87.00,124.00,22.00,22.00,98.00,135.00
|
||||
78.00,129.00,22.00,22.00,89.00,140.00
|
||||
78.00,119.00,22.00,22.00,89.00,130.00
|
||||
74.00,124.00,22.00,22.00,85.00,135.00
|
||||
87.00,133.00,22.00,22.00,98.00,144.00
|
||||
87.00,156.00,22.00,22.00,98.00,167.00
|
||||
78.00,152.00,22.00,22.00,89.00,163.00
|
||||
69.00,147.00,22.00,22.00,80.00,158.00
|
||||
60.00,138.00,22.00,22.00,71.00,149.00
|
||||
55.00,129.00,22.00,22.00,66.00,140.00
|
||||
51.00,115.00,22.00,22.00,62.00,126.00
|
||||
51.00,106.00,22.00,22.00,62.00,117.00
|
||||
46.00,92.00,22.00,22.00,57.00,103.00
|
||||
46.00,83.00,22.00,22.00,57.00,94.00
|
||||
101.00,152.00,22.00,22.00,112.00,163.00
|
||||
110.00,142.00,22.00,22.00,121.00,153.00
|
||||
119.00,133.00,22.00,22.00,130.00,144.00
|
||||
124.00,119.00,22.00,22.00,135.00,130.00
|
||||
129.00,110.00,22.00,22.00,140.00,121.00
|
||||
133.00,101.00,22.00,22.00,144.00,112.00
|
||||
138.00,87.00,22.00,22.00,149.00,98.00
|
||||
138.00,74.00,22.00,22.00,149.00,85.00
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,2 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
69,69,109,109,306,0.0,haar
|
|
@ -0,0 +1,70 @@
|
|||
130,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
68.00,92.00,19.00,19.00,77.50,101.50
|
||||
68.00,92.00,19.00,19.00,77.50,101.50
|
||||
68.00,88.00,19.00,19.00,77.50,97.50
|
||||
72.00,92.00,19.00,19.00,81.50,101.50
|
||||
76.00,92.00,19.00,19.00,85.50,101.50
|
||||
68.00,84.00,19.00,19.00,77.50,93.50
|
||||
68.00,76.00,19.00,19.00,77.50,85.50
|
||||
68.00,68.00,19.00,19.00,77.50,77.50
|
||||
72.00,60.00,19.00,19.00,81.50,69.50
|
||||
60.00,60.00,19.00,19.00,69.50,69.50
|
||||
56.00,60.00,19.00,19.00,65.50,69.50
|
||||
52.00,60.00,19.00,19.00,61.50,69.50
|
||||
56.00,56.00,19.00,19.00,65.50,65.50
|
||||
52.00,56.00,19.00,19.00,61.50,65.50
|
||||
48.00,56.00,19.00,19.00,57.50,65.50
|
||||
40.00,48.00,19.00,19.00,49.50,57.50
|
||||
44.00,44.00,19.00,19.00,53.50,53.50
|
||||
48.00,40.00,19.00,19.00,57.50,49.50
|
||||
56.00,44.00,19.00,19.00,65.50,53.50
|
||||
60.00,48.00,19.00,19.00,69.50,57.50
|
||||
84.00,64.00,19.00,19.00,93.50,73.50
|
||||
88.00,64.00,19.00,19.00,97.50,73.50
|
||||
92.00,64.00,19.00,19.00,101.50,73.50
|
||||
88.00,60.00,19.00,19.00,97.50,69.50
|
||||
92.00,60.00,19.00,19.00,101.50,69.50
|
||||
96.00,64.00,19.00,19.00,105.50,73.50
|
||||
104.00,56.00,19.00,19.00,113.50,65.50
|
||||
100.00,52.00,19.00,19.00,109.50,61.50
|
||||
92.00,52.00,19.00,19.00,101.50,61.50
|
||||
84.00,52.00,19.00,19.00,93.50,61.50
|
||||
76.00,52.00,19.00,19.00,85.50,61.50
|
||||
68.00,96.00,19.00,19.00,77.50,105.50
|
||||
64.00,96.00,19.00,19.00,73.50,105.50
|
||||
60.00,96.00,19.00,19.00,69.50,105.50
|
||||
56.00,100.00,19.00,19.00,65.50,109.50
|
||||
56.00,100.00,19.00,19.00,65.50,109.50
|
||||
64.00,100.00,19.00,19.00,73.50,109.50
|
||||
68.00,100.00,19.00,19.00,77.50,109.50
|
||||
76.00,96.00,19.00,19.00,85.50,105.50
|
||||
80.00,100.00,19.00,19.00,89.50,109.50
|
||||
84.00,100.00,19.00,19.00,93.50,109.50
|
||||
80.00,100.00,19.00,19.00,89.50,109.50
|
||||
80.00,100.00,19.00,19.00,89.50,109.50
|
||||
80.00,104.00,19.00,19.00,89.50,113.50
|
||||
76.00,100.00,19.00,19.00,85.50,109.50
|
||||
76.00,108.00,19.00,19.00,85.50,117.50
|
||||
68.00,104.00,19.00,19.00,77.50,113.50
|
||||
60.00,108.00,19.00,19.00,69.50,117.50
|
||||
60.00,100.00,19.00,19.00,69.50,109.50
|
||||
56.00,104.00,19.00,19.00,65.50,113.50
|
||||
68.00,108.00,19.00,19.00,77.50,117.50
|
||||
72.00,128.00,19.00,19.00,81.50,137.50
|
||||
60.00,124.00,19.00,19.00,69.50,133.50
|
||||
52.00,120.00,19.00,19.00,61.50,129.50
|
||||
44.00,112.00,19.00,19.00,53.50,121.50
|
||||
40.00,104.00,19.00,19.00,49.50,113.50
|
||||
36.00,92.00,19.00,19.00,45.50,101.50
|
||||
32.00,80.00,19.00,19.00,41.50,89.50
|
||||
28.00,68.00,19.00,19.00,37.50,77.50
|
||||
28.00,56.00,19.00,19.00,37.50,65.50
|
||||
80.00,124.00,19.00,19.00,89.50,133.50
|
||||
88.00,120.00,19.00,19.00,97.50,129.50
|
||||
96.00,112.00,19.00,19.00,105.50,121.50
|
||||
100.00,96.00,19.00,19.00,109.50,105.50
|
||||
104.00,84.00,19.00,19.00,113.50,93.50
|
||||
108.00,76.00,19.00,19.00,117.50,85.50
|
||||
116.00,64.00,19.00,19.00,125.50,73.50
|
||||
116.00,56.00,19.00,19.00,125.50,65.50
|
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,4 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
254,40,107,107,345,0.0,haar
|
||||
159,61,87,86,90,22.0,haar
|
||||
20,63,82,82,117,0.0,lbp
|
|
@ -0,0 +1,70 @@
|
|||
157,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
68.00,88.00,19.00,19.00,77.50,97.50
|
||||
64.00,88.00,19.00,19.00,73.50,97.50
|
||||
64.00,88.00,19.00,19.00,73.50,97.50
|
||||
76.00,84.00,19.00,19.00,85.50,93.50
|
||||
80.00,84.00,19.00,19.00,89.50,93.50
|
||||
68.00,80.00,19.00,19.00,77.50,89.50
|
||||
68.00,76.00,19.00,19.00,77.50,85.50
|
||||
68.00,68.00,19.00,19.00,77.50,77.50
|
||||
68.00,60.00,19.00,19.00,77.50,69.50
|
||||
56.00,60.00,19.00,19.00,65.50,69.50
|
||||
56.00,64.00,19.00,19.00,65.50,73.50
|
||||
52.00,64.00,19.00,19.00,61.50,73.50
|
||||
52.00,60.00,19.00,19.00,61.50,69.50
|
||||
52.00,60.00,19.00,19.00,61.50,69.50
|
||||
48.00,64.00,19.00,19.00,57.50,73.50
|
||||
36.00,56.00,19.00,19.00,45.50,65.50
|
||||
40.00,52.00,19.00,19.00,49.50,61.50
|
||||
48.00,48.00,19.00,19.00,57.50,57.50
|
||||
56.00,48.00,19.00,19.00,65.50,57.50
|
||||
64.00,48.00,19.00,19.00,73.50,57.50
|
||||
80.00,56.00,19.00,19.00,89.50,65.50
|
||||
84.00,56.00,19.00,19.00,93.50,65.50
|
||||
88.00,56.00,19.00,19.00,97.50,65.50
|
||||
84.00,52.00,19.00,19.00,93.50,61.50
|
||||
88.00,52.00,19.00,19.00,97.50,61.50
|
||||
92.00,52.00,19.00,19.00,101.50,61.50
|
||||
104.00,44.00,19.00,19.00,113.50,53.50
|
||||
104.00,40.00,19.00,19.00,113.50,49.50
|
||||
96.00,40.00,19.00,19.00,105.50,49.50
|
||||
88.00,44.00,19.00,19.00,97.50,53.50
|
||||
80.00,48.00,19.00,19.00,89.50,57.50
|
||||
68.00,92.00,19.00,19.00,77.50,101.50
|
||||
64.00,92.00,19.00,19.00,73.50,101.50
|
||||
60.00,96.00,19.00,19.00,69.50,105.50
|
||||
56.00,100.00,19.00,19.00,65.50,109.50
|
||||
60.00,100.00,19.00,19.00,69.50,109.50
|
||||
64.00,96.00,19.00,19.00,73.50,105.50
|
||||
68.00,96.00,19.00,19.00,77.50,105.50
|
||||
76.00,88.00,19.00,19.00,85.50,97.50
|
||||
84.00,92.00,19.00,19.00,93.50,101.50
|
||||
88.00,96.00,19.00,19.00,97.50,105.50
|
||||
88.00,92.00,19.00,19.00,97.50,101.50
|
||||
80.00,92.00,19.00,19.00,89.50,101.50
|
||||
88.00,108.00,19.00,19.00,97.50,117.50
|
||||
84.00,104.00,19.00,19.00,93.50,113.50
|
||||
84.00,112.00,19.00,19.00,93.50,121.50
|
||||
76.00,108.00,19.00,19.00,85.50,117.50
|
||||
68.00,112.00,19.00,19.00,77.50,121.50
|
||||
68.00,104.00,19.00,19.00,77.50,113.50
|
||||
64.00,104.00,19.00,19.00,73.50,113.50
|
||||
76.00,112.00,19.00,19.00,85.50,121.50
|
||||
76.00,128.00,19.00,19.00,85.50,137.50
|
||||
68.00,124.00,19.00,19.00,77.50,133.50
|
||||
60.00,116.00,19.00,19.00,69.50,125.50
|
||||
52.00,108.00,19.00,19.00,61.50,117.50
|
||||
44.00,104.00,19.00,19.00,53.50,113.50
|
||||
40.00,96.00,19.00,19.00,49.50,105.50
|
||||
40.00,88.00,19.00,19.00,49.50,97.50
|
||||
36.00,76.00,19.00,19.00,45.50,85.50
|
||||
36.00,68.00,19.00,19.00,45.50,77.50
|
||||
84.00,124.00,19.00,19.00,93.50,133.50
|
||||
92.00,116.00,19.00,19.00,101.50,125.50
|
||||
100.00,112.00,19.00,19.00,109.50,121.50
|
||||
104.00,100.00,19.00,19.00,113.50,109.50
|
||||
108.00,92.00,19.00,19.00,117.50,101.50
|
||||
112.00,80.00,19.00,19.00,121.50,89.50
|
||||
112.00,68.00,19.00,19.00,121.50,77.50
|
||||
112.00,60.00,19.00,19.00,121.50,69.50
|
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,70 @@
|
|||
67,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
60.00,76.00,19.00,19.00,69.50,85.50
|
||||
60.00,76.00,19.00,19.00,69.50,85.50
|
||||
56.00,72.00,19.00,19.00,65.50,81.50
|
||||
64.00,72.00,19.00,19.00,73.50,81.50
|
||||
64.00,72.00,19.00,19.00,73.50,81.50
|
||||
60.00,68.00,19.00,19.00,69.50,77.50
|
||||
60.00,64.00,19.00,19.00,69.50,73.50
|
||||
56.00,56.00,19.00,19.00,65.50,65.50
|
||||
56.00,52.00,19.00,19.00,65.50,61.50
|
||||
44.00,52.00,19.00,19.00,53.50,61.50
|
||||
40.00,56.00,19.00,19.00,49.50,65.50
|
||||
36.00,56.00,19.00,19.00,45.50,65.50
|
||||
40.00,52.00,19.00,19.00,49.50,61.50
|
||||
40.00,52.00,19.00,19.00,49.50,61.50
|
||||
36.00,56.00,19.00,19.00,45.50,65.50
|
||||
24.00,48.00,19.00,19.00,33.50,57.50
|
||||
28.00,44.00,19.00,19.00,37.50,53.50
|
||||
32.00,40.00,19.00,19.00,41.50,49.50
|
||||
40.00,44.00,19.00,19.00,49.50,53.50
|
||||
48.00,44.00,19.00,19.00,57.50,53.50
|
||||
64.00,48.00,19.00,19.00,73.50,57.50
|
||||
68.00,48.00,19.00,19.00,77.50,57.50
|
||||
72.00,48.00,19.00,19.00,81.50,57.50
|
||||
68.00,44.00,19.00,19.00,77.50,53.50
|
||||
72.00,44.00,19.00,19.00,81.50,53.50
|
||||
76.00,44.00,19.00,19.00,85.50,53.50
|
||||
84.00,36.00,19.00,19.00,93.50,45.50
|
||||
80.00,32.00,19.00,19.00,89.50,41.50
|
||||
72.00,28.00,19.00,19.00,81.50,37.50
|
||||
68.00,28.00,19.00,19.00,77.50,37.50
|
||||
64.00,32.00,19.00,19.00,73.50,41.50
|
||||
60.00,80.00,19.00,19.00,69.50,89.50
|
||||
56.00,84.00,19.00,19.00,65.50,93.50
|
||||
52.00,88.00,19.00,19.00,61.50,97.50
|
||||
52.00,96.00,19.00,19.00,61.50,105.50
|
||||
52.00,96.00,19.00,19.00,61.50,105.50
|
||||
56.00,84.00,19.00,19.00,65.50,93.50
|
||||
60.00,84.00,19.00,19.00,69.50,93.50
|
||||
68.00,80.00,19.00,19.00,77.50,89.50
|
||||
72.00,80.00,19.00,19.00,81.50,89.50
|
||||
76.00,80.00,19.00,19.00,85.50,89.50
|
||||
72.00,84.00,19.00,19.00,81.50,93.50
|
||||
68.00,84.00,19.00,19.00,77.50,93.50
|
||||
76.00,84.00,19.00,19.00,85.50,93.50
|
||||
72.00,80.00,19.00,19.00,81.50,89.50
|
||||
72.00,84.00,19.00,19.00,81.50,93.50
|
||||
64.00,80.00,19.00,19.00,73.50,89.50
|
||||
56.00,84.00,19.00,19.00,65.50,93.50
|
||||
56.00,76.00,19.00,19.00,65.50,85.50
|
||||
52.00,76.00,19.00,19.00,61.50,85.50
|
||||
64.00,84.00,19.00,19.00,73.50,93.50
|
||||
64.00,100.00,19.00,19.00,73.50,109.50
|
||||
56.00,96.00,19.00,19.00,65.50,105.50
|
||||
48.00,88.00,19.00,19.00,57.50,97.50
|
||||
40.00,76.00,19.00,19.00,49.50,85.50
|
||||
32.00,68.00,19.00,19.00,41.50,77.50
|
||||
28.00,56.00,19.00,19.00,37.50,65.50
|
||||
24.00,44.00,19.00,19.00,33.50,53.50
|
||||
20.00,32.00,19.00,19.00,29.50,41.50
|
||||
20.00,20.00,19.00,19.00,29.50,29.50
|
||||
72.00,96.00,19.00,19.00,81.50,105.50
|
||||
80.00,88.00,19.00,19.00,89.50,97.50
|
||||
84.00,80.00,19.00,19.00,93.50,89.50
|
||||
88.00,68.00,19.00,19.00,97.50,77.50
|
||||
88.00,56.00,19.00,19.00,97.50,65.50
|
||||
92.00,44.00,19.00,19.00,101.50,53.50
|
||||
92.00,32.00,19.00,19.00,101.50,41.50
|
||||
92.00,20.00,19.00,19.00,101.50,29.50
|
After Width: | Height: | Size: 8.1 KiB |
|
@ -0,0 +1,70 @@
|
|||
145,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
48.00,64.00,19.00,19.00,57.50,73.50
|
||||
48.00,64.00,19.00,19.00,57.50,73.50
|
||||
44.00,64.00,19.00,19.00,53.50,73.50
|
||||
52.00,64.00,19.00,19.00,61.50,73.50
|
||||
56.00,64.00,19.00,19.00,65.50,73.50
|
||||
48.00,60.00,19.00,19.00,57.50,69.50
|
||||
48.00,56.00,19.00,19.00,57.50,65.50
|
||||
48.00,48.00,19.00,19.00,57.50,57.50
|
||||
52.00,44.00,19.00,19.00,61.50,53.50
|
||||
40.00,44.00,19.00,19.00,49.50,53.50
|
||||
36.00,44.00,19.00,19.00,45.50,53.50
|
||||
36.00,44.00,19.00,19.00,45.50,53.50
|
||||
36.00,40.00,19.00,19.00,45.50,49.50
|
||||
36.00,40.00,19.00,19.00,45.50,49.50
|
||||
32.00,44.00,19.00,19.00,41.50,53.50
|
||||
20.00,36.00,19.00,19.00,29.50,45.50
|
||||
24.00,32.00,19.00,19.00,33.50,41.50
|
||||
28.00,28.00,19.00,19.00,37.50,37.50
|
||||
36.00,32.00,19.00,19.00,45.50,41.50
|
||||
40.00,36.00,19.00,19.00,49.50,45.50
|
||||
60.00,44.00,19.00,19.00,69.50,53.50
|
||||
64.00,44.00,19.00,19.00,73.50,53.50
|
||||
64.00,44.00,19.00,19.00,73.50,53.50
|
||||
64.00,40.00,19.00,19.00,73.50,49.50
|
||||
64.00,40.00,19.00,19.00,73.50,49.50
|
||||
68.00,44.00,19.00,19.00,77.50,53.50
|
||||
76.00,36.00,19.00,19.00,85.50,45.50
|
||||
72.00,36.00,19.00,19.00,81.50,45.50
|
||||
68.00,32.00,19.00,19.00,77.50,41.50
|
||||
64.00,32.00,19.00,19.00,73.50,41.50
|
||||
56.00,32.00,19.00,19.00,65.50,41.50
|
||||
48.00,68.00,19.00,19.00,57.50,77.50
|
||||
44.00,64.00,19.00,19.00,53.50,73.50
|
||||
40.00,68.00,19.00,19.00,49.50,77.50
|
||||
36.00,72.00,19.00,19.00,45.50,81.50
|
||||
36.00,72.00,19.00,19.00,45.50,81.50
|
||||
44.00,68.00,19.00,19.00,53.50,77.50
|
||||
48.00,72.00,19.00,19.00,57.50,81.50
|
||||
56.00,64.00,19.00,19.00,65.50,73.50
|
||||
60.00,68.00,19.00,19.00,69.50,77.50
|
||||
64.00,68.00,19.00,19.00,73.50,77.50
|
||||
60.00,72.00,19.00,19.00,69.50,81.50
|
||||
60.00,68.00,19.00,19.00,69.50,77.50
|
||||
60.00,76.00,19.00,19.00,69.50,85.50
|
||||
56.00,72.00,19.00,19.00,65.50,81.50
|
||||
56.00,80.00,19.00,19.00,65.50,89.50
|
||||
48.00,76.00,19.00,19.00,57.50,85.50
|
||||
40.00,76.00,19.00,19.00,49.50,85.50
|
||||
40.00,68.00,19.00,19.00,49.50,77.50
|
||||
36.00,72.00,19.00,19.00,45.50,81.50
|
||||
48.00,80.00,19.00,19.00,57.50,89.50
|
||||
48.00,100.00,19.00,19.00,57.50,109.50
|
||||
40.00,96.00,19.00,19.00,49.50,105.50
|
||||
36.00,92.00,19.00,19.00,45.50,101.50
|
||||
28.00,84.00,19.00,19.00,37.50,93.50
|
||||
24.00,80.00,19.00,19.00,33.50,89.50
|
||||
20.00,72.00,19.00,19.00,29.50,81.50
|
||||
20.00,64.00,19.00,19.00,29.50,73.50
|
||||
16.00,52.00,19.00,19.00,25.50,61.50
|
||||
16.00,44.00,19.00,19.00,25.50,53.50
|
||||
56.00,96.00,19.00,19.00,65.50,105.50
|
||||
64.00,88.00,19.00,19.00,73.50,97.50
|
||||
72.00,84.00,19.00,19.00,81.50,93.50
|
||||
76.00,76.00,19.00,19.00,85.50,85.50
|
||||
76.00,68.00,19.00,19.00,85.50,77.50
|
||||
76.00,60.00,19.00,19.00,85.50,69.50
|
||||
80.00,48.00,19.00,19.00,89.50,57.50
|
||||
80.00,40.00,19.00,19.00,89.50,49.50
|
After Width: | Height: | Size: 8.3 KiB |
|
@ -0,0 +1,5 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
327,101,121,121,154,0.0,lbp
|
||||
237,106,113,113,139,0.0,lbp
|
||||
164,49,91,91,49,0.0,lbp
|
||||
434,86,94,94,95,0.0,lbp
|
|
@ -0,0 +1,70 @@
|
|||
119,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
74.00,84.00,25.00,25.00,86.50,96.50
|
||||
69.00,84.00,25.00,25.00,81.50,96.50
|
||||
69.00,79.00,25.00,25.00,81.50,91.50
|
||||
79.00,79.00,25.00,25.00,91.50,91.50
|
||||
84.00,79.00,25.00,25.00,96.50,91.50
|
||||
74.00,79.00,25.00,25.00,86.50,91.50
|
||||
74.00,74.00,25.00,25.00,86.50,86.50
|
||||
74.00,69.00,25.00,25.00,86.50,81.50
|
||||
74.00,63.00,25.00,25.00,86.50,75.50
|
||||
58.00,63.00,25.00,25.00,70.50,75.50
|
||||
58.00,63.00,25.00,25.00,70.50,75.50
|
||||
53.00,69.00,25.00,25.00,65.50,81.50
|
||||
53.00,63.00,25.00,25.00,65.50,75.50
|
||||
53.00,63.00,25.00,25.00,65.50,75.50
|
||||
48.00,69.00,25.00,25.00,60.50,81.50
|
||||
37.00,58.00,25.00,25.00,49.50,70.50
|
||||
42.00,53.00,25.00,25.00,54.50,65.50
|
||||
48.00,48.00,25.00,25.00,60.50,60.50
|
||||
58.00,53.00,25.00,25.00,70.50,65.50
|
||||
63.00,53.00,25.00,25.00,75.50,65.50
|
||||
90.00,63.00,25.00,25.00,102.50,75.50
|
||||
95.00,63.00,25.00,25.00,107.50,75.50
|
||||
100.00,63.00,25.00,25.00,112.50,75.50
|
||||
95.00,63.00,25.00,25.00,107.50,75.50
|
||||
100.00,63.00,25.00,25.00,112.50,75.50
|
||||
106.00,63.00,25.00,25.00,118.50,75.50
|
||||
116.00,53.00,25.00,25.00,128.50,65.50
|
||||
111.00,53.00,25.00,25.00,123.50,65.50
|
||||
100.00,48.00,25.00,25.00,112.50,60.50
|
||||
95.00,48.00,25.00,25.00,107.50,60.50
|
||||
84.00,53.00,25.00,25.00,96.50,65.50
|
||||
74.00,90.00,25.00,25.00,86.50,102.50
|
||||
63.00,90.00,25.00,25.00,75.50,102.50
|
||||
58.00,95.00,25.00,25.00,70.50,107.50
|
||||
53.00,100.00,25.00,25.00,65.50,112.50
|
||||
58.00,106.00,25.00,25.00,70.50,118.50
|
||||
63.00,95.00,25.00,25.00,75.50,107.50
|
||||
74.00,90.00,25.00,25.00,86.50,102.50
|
||||
84.00,90.00,25.00,25.00,96.50,102.50
|
||||
95.00,95.00,25.00,25.00,107.50,107.50
|
||||
100.00,100.00,25.00,25.00,112.50,112.50
|
||||
100.00,100.00,25.00,25.00,112.50,112.50
|
||||
84.00,95.00,25.00,25.00,96.50,107.50
|
||||
95.00,111.00,25.00,25.00,107.50,123.50
|
||||
90.00,106.00,25.00,25.00,102.50,118.50
|
||||
90.00,116.00,25.00,25.00,102.50,128.50
|
||||
79.00,111.00,25.00,25.00,91.50,123.50
|
||||
63.00,116.00,25.00,25.00,75.50,128.50
|
||||
63.00,106.00,25.00,25.00,75.50,118.50
|
||||
58.00,111.00,25.00,25.00,70.50,123.50
|
||||
79.00,116.00,25.00,25.00,91.50,128.50
|
||||
84.00,143.00,25.00,25.00,96.50,155.50
|
||||
69.00,137.00,25.00,25.00,81.50,149.50
|
||||
58.00,127.00,25.00,25.00,70.50,139.50
|
||||
48.00,116.00,25.00,25.00,60.50,128.50
|
||||
42.00,100.00,25.00,25.00,54.50,112.50
|
||||
37.00,84.00,25.00,25.00,49.50,96.50
|
||||
32.00,69.00,25.00,25.00,44.50,81.50
|
||||
26.00,48.00,25.00,25.00,38.50,60.50
|
||||
26.00,32.00,25.00,25.00,38.50,44.50
|
||||
95.00,137.00,25.00,25.00,107.50,149.50
|
||||
106.00,127.00,25.00,25.00,118.50,139.50
|
||||
116.00,121.00,25.00,25.00,128.50,133.50
|
||||
121.00,111.00,25.00,25.00,133.50,123.50
|
||||
127.00,100.00,25.00,25.00,139.50,112.50
|
||||
132.00,90.00,25.00,25.00,144.50,102.50
|
||||
132.00,74.00,25.00,25.00,144.50,86.50
|
||||
132.00,58.00,25.00,25.00,144.50,70.50
|
After Width: | Height: | Size: 18 KiB |
|
@ -0,0 +1,70 @@
|
|||
84,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
74.00,92.00,22.00,22.00,85.00,103.00
|
||||
69.00,92.00,22.00,22.00,80.00,103.00
|
||||
64.00,92.00,22.00,22.00,75.00,103.00
|
||||
78.00,92.00,22.00,22.00,89.00,103.00
|
||||
83.00,92.00,22.00,22.00,94.00,103.00
|
||||
74.00,83.00,22.00,22.00,85.00,94.00
|
||||
74.00,78.00,22.00,22.00,85.00,89.00
|
||||
74.00,69.00,22.00,22.00,85.00,80.00
|
||||
74.00,60.00,22.00,22.00,85.00,71.00
|
||||
60.00,60.00,22.00,22.00,71.00,71.00
|
||||
60.00,60.00,22.00,22.00,71.00,71.00
|
||||
55.00,60.00,22.00,22.00,66.00,71.00
|
||||
55.00,55.00,22.00,22.00,66.00,66.00
|
||||
51.00,55.00,22.00,22.00,62.00,66.00
|
||||
46.00,55.00,22.00,22.00,57.00,66.00
|
||||
37.00,51.00,22.00,22.00,48.00,62.00
|
||||
41.00,46.00,22.00,22.00,52.00,57.00
|
||||
46.00,41.00,22.00,22.00,57.00,52.00
|
||||
55.00,46.00,22.00,22.00,66.00,57.00
|
||||
64.00,51.00,22.00,22.00,75.00,62.00
|
||||
87.00,64.00,22.00,22.00,98.00,75.00
|
||||
92.00,64.00,22.00,22.00,103.00,75.00
|
||||
96.00,64.00,22.00,22.00,107.00,75.00
|
||||
92.00,64.00,22.00,22.00,103.00,75.00
|
||||
92.00,64.00,22.00,22.00,103.00,75.00
|
||||
96.00,64.00,22.00,22.00,107.00,75.00
|
||||
106.00,55.00,22.00,22.00,117.00,66.00
|
||||
101.00,51.00,22.00,22.00,112.00,62.00
|
||||
92.00,51.00,22.00,22.00,103.00,62.00
|
||||
87.00,51.00,22.00,22.00,98.00,62.00
|
||||
83.00,51.00,22.00,22.00,94.00,62.00
|
||||
74.00,96.00,22.00,22.00,85.00,107.00
|
||||
69.00,96.00,22.00,22.00,80.00,107.00
|
||||
60.00,101.00,22.00,22.00,71.00,112.00
|
||||
55.00,110.00,22.00,22.00,66.00,121.00
|
||||
55.00,110.00,22.00,22.00,66.00,121.00
|
||||
69.00,101.00,22.00,22.00,80.00,112.00
|
||||
74.00,101.00,22.00,22.00,85.00,112.00
|
||||
83.00,92.00,22.00,22.00,94.00,103.00
|
||||
87.00,96.00,22.00,22.00,98.00,107.00
|
||||
87.00,101.00,22.00,22.00,98.00,112.00
|
||||
87.00,101.00,22.00,22.00,98.00,112.00
|
||||
83.00,96.00,22.00,22.00,94.00,107.00
|
||||
83.00,110.00,22.00,22.00,94.00,121.00
|
||||
78.00,106.00,22.00,22.00,89.00,117.00
|
||||
78.00,110.00,22.00,22.00,89.00,121.00
|
||||
64.00,106.00,22.00,22.00,75.00,117.00
|
||||
55.00,110.00,22.00,22.00,66.00,121.00
|
||||
55.00,101.00,22.00,22.00,66.00,112.00
|
||||
51.00,101.00,22.00,22.00,62.00,112.00
|
||||
64.00,110.00,22.00,22.00,75.00,121.00
|
||||
69.00,133.00,22.00,22.00,80.00,144.00
|
||||
55.00,129.00,22.00,22.00,66.00,140.00
|
||||
46.00,119.00,22.00,22.00,57.00,130.00
|
||||
37.00,110.00,22.00,22.00,48.00,121.00
|
||||
28.00,106.00,22.00,22.00,39.00,117.00
|
||||
23.00,96.00,22.00,22.00,34.00,107.00
|
||||
23.00,87.00,22.00,22.00,34.00,98.00
|
||||
18.00,74.00,22.00,22.00,29.00,85.00
|
||||
18.00,60.00,22.00,22.00,29.00,71.00
|
||||
78.00,129.00,22.00,22.00,89.00,140.00
|
||||
87.00,124.00,22.00,22.00,98.00,135.00
|
||||
101.00,115.00,22.00,22.00,112.00,126.00
|
||||
101.00,101.00,22.00,22.00,112.00,112.00
|
||||
106.00,92.00,22.00,22.00,117.00,103.00
|
||||
110.00,83.00,22.00,22.00,121.00,94.00
|
||||
115.00,69.00,22.00,22.00,126.00,80.00
|
||||
115.00,55.00,22.00,22.00,126.00,66.00
|
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,70 @@
|
|||
80,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
60.00,72.00,19.00,19.00,69.50,81.50
|
||||
56.00,72.00,19.00,19.00,65.50,81.50
|
||||
52.00,72.00,19.00,19.00,61.50,81.50
|
||||
64.00,68.00,19.00,19.00,73.50,77.50
|
||||
68.00,68.00,19.00,19.00,77.50,77.50
|
||||
60.00,64.00,19.00,19.00,69.50,73.50
|
||||
60.00,60.00,19.00,19.00,69.50,69.50
|
||||
60.00,52.00,19.00,19.00,69.50,61.50
|
||||
60.00,48.00,19.00,19.00,69.50,57.50
|
||||
48.00,48.00,19.00,19.00,57.50,57.50
|
||||
44.00,48.00,19.00,19.00,53.50,57.50
|
||||
40.00,48.00,19.00,19.00,49.50,57.50
|
||||
44.00,48.00,19.00,19.00,53.50,57.50
|
||||
44.00,48.00,19.00,19.00,53.50,57.50
|
||||
40.00,48.00,19.00,19.00,49.50,57.50
|
||||
32.00,44.00,19.00,19.00,41.50,53.50
|
||||
36.00,40.00,19.00,19.00,45.50,49.50
|
||||
40.00,40.00,19.00,19.00,49.50,49.50
|
||||
44.00,44.00,19.00,19.00,53.50,53.50
|
||||
48.00,44.00,19.00,19.00,57.50,53.50
|
||||
72.00,48.00,19.00,19.00,81.50,57.50
|
||||
76.00,48.00,19.00,19.00,85.50,57.50
|
||||
76.00,48.00,19.00,19.00,85.50,57.50
|
||||
76.00,44.00,19.00,19.00,85.50,53.50
|
||||
80.00,44.00,19.00,19.00,89.50,53.50
|
||||
84.00,44.00,19.00,19.00,93.50,53.50
|
||||
96.00,40.00,19.00,19.00,105.50,49.50
|
||||
92.00,36.00,19.00,19.00,101.50,45.50
|
||||
84.00,36.00,19.00,19.00,93.50,45.50
|
||||
76.00,36.00,19.00,19.00,85.50,45.50
|
||||
68.00,40.00,19.00,19.00,77.50,49.50
|
||||
60.00,76.00,19.00,19.00,69.50,85.50
|
||||
52.00,72.00,19.00,19.00,61.50,81.50
|
||||
44.00,76.00,19.00,19.00,53.50,85.50
|
||||
40.00,80.00,19.00,19.00,49.50,89.50
|
||||
44.00,80.00,19.00,19.00,53.50,89.50
|
||||
48.00,76.00,19.00,19.00,57.50,85.50
|
||||
60.00,80.00,19.00,19.00,69.50,89.50
|
||||
68.00,72.00,19.00,19.00,77.50,81.50
|
||||
76.00,72.00,19.00,19.00,85.50,81.50
|
||||
80.00,76.00,19.00,19.00,89.50,85.50
|
||||
80.00,76.00,19.00,19.00,89.50,85.50
|
||||
68.00,76.00,19.00,19.00,77.50,85.50
|
||||
76.00,84.00,19.00,19.00,85.50,93.50
|
||||
68.00,80.00,19.00,19.00,77.50,89.50
|
||||
68.00,88.00,19.00,19.00,77.50,97.50
|
||||
60.00,84.00,19.00,19.00,69.50,93.50
|
||||
52.00,88.00,19.00,19.00,61.50,97.50
|
||||
52.00,80.00,19.00,19.00,61.50,89.50
|
||||
48.00,84.00,19.00,19.00,57.50,93.50
|
||||
60.00,88.00,19.00,19.00,69.50,97.50
|
||||
60.00,104.00,19.00,19.00,69.50,113.50
|
||||
52.00,104.00,19.00,19.00,61.50,113.50
|
||||
44.00,96.00,19.00,19.00,53.50,105.50
|
||||
36.00,88.00,19.00,19.00,45.50,97.50
|
||||
28.00,84.00,19.00,19.00,37.50,93.50
|
||||
24.00,76.00,19.00,19.00,33.50,85.50
|
||||
24.00,68.00,19.00,19.00,33.50,77.50
|
||||
20.00,56.00,19.00,19.00,29.50,65.50
|
||||
20.00,48.00,19.00,19.00,29.50,57.50
|
||||
72.00,100.00,19.00,19.00,81.50,109.50
|
||||
80.00,92.00,19.00,19.00,89.50,101.50
|
||||
92.00,84.00,19.00,19.00,101.50,93.50
|
||||
96.00,72.00,19.00,19.00,105.50,81.50
|
||||
100.00,64.00,19.00,19.00,109.50,73.50
|
||||
100.00,56.00,19.00,19.00,109.50,65.50
|
||||
104.00,44.00,19.00,19.00,113.50,53.50
|
||||
104.00,36.00,19.00,19.00,113.50,45.50
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,70 @@
|
|||
110,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
60.00,74.00,22.00,22.00,71.00,85.00
|
||||
55.00,74.00,22.00,22.00,66.00,85.00
|
||||
51.00,74.00,22.00,22.00,62.00,85.00
|
||||
64.00,74.00,22.00,22.00,75.00,85.00
|
||||
69.00,74.00,22.00,22.00,80.00,85.00
|
||||
60.00,64.00,22.00,22.00,71.00,75.00
|
||||
60.00,60.00,22.00,22.00,71.00,71.00
|
||||
60.00,51.00,22.00,22.00,71.00,62.00
|
||||
60.00,46.00,22.00,22.00,71.00,57.00
|
||||
46.00,46.00,22.00,22.00,57.00,57.00
|
||||
41.00,46.00,22.00,22.00,52.00,57.00
|
||||
41.00,46.00,22.00,22.00,52.00,57.00
|
||||
41.00,41.00,22.00,22.00,52.00,52.00
|
||||
41.00,41.00,22.00,22.00,52.00,52.00
|
||||
37.00,46.00,22.00,22.00,48.00,57.00
|
||||
23.00,41.00,22.00,22.00,34.00,52.00
|
||||
28.00,37.00,22.00,22.00,39.00,48.00
|
||||
32.00,32.00,22.00,22.00,43.00,43.00
|
||||
41.00,37.00,22.00,22.00,52.00,48.00
|
||||
51.00,41.00,22.00,22.00,62.00,52.00
|
||||
69.00,46.00,22.00,22.00,80.00,57.00
|
||||
74.00,46.00,22.00,22.00,85.00,57.00
|
||||
78.00,46.00,22.00,22.00,89.00,57.00
|
||||
74.00,46.00,22.00,22.00,85.00,57.00
|
||||
78.00,46.00,22.00,22.00,89.00,57.00
|
||||
83.00,46.00,22.00,22.00,94.00,57.00
|
||||
92.00,37.00,22.00,22.00,103.00,48.00
|
||||
87.00,37.00,22.00,22.00,98.00,48.00
|
||||
78.00,37.00,22.00,22.00,89.00,48.00
|
||||
74.00,37.00,22.00,22.00,85.00,48.00
|
||||
64.00,37.00,22.00,22.00,75.00,48.00
|
||||
60.00,78.00,22.00,22.00,71.00,89.00
|
||||
55.00,74.00,22.00,22.00,66.00,85.00
|
||||
46.00,74.00,22.00,22.00,57.00,85.00
|
||||
41.00,78.00,22.00,22.00,52.00,89.00
|
||||
46.00,78.00,22.00,22.00,57.00,89.00
|
||||
51.00,78.00,22.00,22.00,62.00,89.00
|
||||
60.00,83.00,22.00,22.00,71.00,94.00
|
||||
69.00,74.00,22.00,22.00,80.00,85.00
|
||||
74.00,78.00,22.00,22.00,85.00,89.00
|
||||
78.00,78.00,22.00,22.00,89.00,89.00
|
||||
78.00,78.00,22.00,22.00,89.00,89.00
|
||||
74.00,78.00,22.00,22.00,85.00,89.00
|
||||
74.00,87.00,22.00,22.00,85.00,98.00
|
||||
64.00,83.00,22.00,22.00,75.00,94.00
|
||||
64.00,92.00,22.00,22.00,75.00,103.00
|
||||
55.00,87.00,22.00,22.00,66.00,98.00
|
||||
46.00,92.00,22.00,22.00,57.00,103.00
|
||||
46.00,83.00,22.00,22.00,57.00,94.00
|
||||
41.00,83.00,22.00,22.00,52.00,94.00
|
||||
55.00,92.00,22.00,22.00,66.00,103.00
|
||||
60.00,115.00,22.00,22.00,71.00,126.00
|
||||
51.00,110.00,22.00,22.00,62.00,121.00
|
||||
41.00,101.00,22.00,22.00,52.00,112.00
|
||||
32.00,92.00,22.00,22.00,43.00,103.00
|
||||
28.00,83.00,22.00,22.00,39.00,94.00
|
||||
23.00,74.00,22.00,22.00,34.00,85.00
|
||||
18.00,64.00,22.00,22.00,29.00,75.00
|
||||
14.00,51.00,22.00,22.00,25.00,62.00
|
||||
14.00,37.00,22.00,22.00,25.00,48.00
|
||||
69.00,115.00,22.00,22.00,80.00,126.00
|
||||
78.00,110.00,22.00,22.00,89.00,121.00
|
||||
87.00,101.00,22.00,22.00,98.00,112.00
|
||||
92.00,87.00,22.00,22.00,103.00,98.00
|
||||
96.00,74.00,22.00,22.00,107.00,85.00
|
||||
101.00,64.00,22.00,22.00,112.00,75.00
|
||||
106.00,51.00,22.00,22.00,117.00,62.00
|
||||
106.00,41.00,22.00,22.00,117.00,52.00
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,70 @@
|
|||
252,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
111.00,132.00,25.00,25.00,123.50,144.50
|
||||
111.00,132.00,25.00,25.00,123.50,144.50
|
||||
106.00,132.00,25.00,25.00,118.50,144.50
|
||||
116.00,132.00,25.00,25.00,128.50,144.50
|
||||
121.00,132.00,25.00,25.00,133.50,144.50
|
||||
111.00,121.00,25.00,25.00,123.50,133.50
|
||||
111.00,116.00,25.00,25.00,123.50,128.50
|
||||
111.00,106.00,25.00,25.00,123.50,118.50
|
||||
111.00,100.00,25.00,25.00,123.50,112.50
|
||||
100.00,100.00,25.00,25.00,112.50,112.50
|
||||
95.00,100.00,25.00,25.00,107.50,112.50
|
||||
90.00,100.00,25.00,25.00,102.50,112.50
|
||||
95.00,95.00,25.00,25.00,107.50,107.50
|
||||
90.00,95.00,25.00,25.00,102.50,107.50
|
||||
84.00,100.00,25.00,25.00,96.50,112.50
|
||||
74.00,90.00,25.00,25.00,86.50,102.50
|
||||
79.00,84.00,25.00,25.00,91.50,96.50
|
||||
84.00,79.00,25.00,25.00,96.50,91.50
|
||||
95.00,84.00,25.00,25.00,107.50,96.50
|
||||
106.00,84.00,25.00,25.00,118.50,96.50
|
||||
127.00,100.00,25.00,25.00,139.50,112.50
|
||||
132.00,100.00,25.00,25.00,144.50,112.50
|
||||
132.00,100.00,25.00,25.00,144.50,112.50
|
||||
127.00,95.00,25.00,25.00,139.50,107.50
|
||||
132.00,95.00,25.00,25.00,144.50,107.50
|
||||
137.00,100.00,25.00,25.00,149.50,112.50
|
||||
148.00,90.00,25.00,25.00,160.50,102.50
|
||||
143.00,84.00,25.00,25.00,155.50,96.50
|
||||
132.00,84.00,25.00,25.00,144.50,96.50
|
||||
127.00,84.00,25.00,25.00,139.50,96.50
|
||||
116.00,84.00,25.00,25.00,128.50,96.50
|
||||
111.00,137.00,25.00,25.00,123.50,149.50
|
||||
106.00,137.00,25.00,25.00,118.50,149.50
|
||||
100.00,143.00,25.00,25.00,112.50,155.50
|
||||
95.00,148.00,25.00,25.00,107.50,160.50
|
||||
100.00,148.00,25.00,25.00,112.50,160.50
|
||||
106.00,143.00,25.00,25.00,118.50,155.50
|
||||
111.00,143.00,25.00,25.00,123.50,155.50
|
||||
121.00,137.00,25.00,25.00,133.50,149.50
|
||||
127.00,143.00,25.00,25.00,139.50,155.50
|
||||
132.00,143.00,25.00,25.00,144.50,155.50
|
||||
127.00,143.00,25.00,25.00,139.50,155.50
|
||||
127.00,143.00,25.00,25.00,139.50,155.50
|
||||
127.00,153.00,25.00,25.00,139.50,165.50
|
||||
121.00,148.00,25.00,25.00,133.50,160.50
|
||||
121.00,158.00,25.00,25.00,133.50,170.50
|
||||
111.00,153.00,25.00,25.00,123.50,165.50
|
||||
106.00,158.00,25.00,25.00,118.50,170.50
|
||||
106.00,148.00,25.00,25.00,118.50,160.50
|
||||
100.00,153.00,25.00,25.00,112.50,165.50
|
||||
111.00,158.00,25.00,25.00,123.50,170.50
|
||||
116.00,185.00,25.00,25.00,128.50,197.50
|
||||
106.00,179.00,25.00,25.00,118.50,191.50
|
||||
95.00,174.00,25.00,25.00,107.50,186.50
|
||||
84.00,164.00,25.00,25.00,96.50,176.50
|
||||
79.00,153.00,25.00,25.00,91.50,165.50
|
||||
74.00,143.00,25.00,25.00,86.50,155.50
|
||||
74.00,132.00,25.00,25.00,86.50,144.50
|
||||
74.00,116.00,25.00,25.00,86.50,128.50
|
||||
74.00,100.00,25.00,25.00,86.50,112.50
|
||||
127.00,179.00,25.00,25.00,139.50,191.50
|
||||
137.00,174.00,25.00,25.00,149.50,186.50
|
||||
143.00,164.00,25.00,25.00,155.50,176.50
|
||||
148.00,148.00,25.00,25.00,160.50,160.50
|
||||
153.00,137.00,25.00,25.00,165.50,149.50
|
||||
158.00,127.00,25.00,25.00,170.50,139.50
|
||||
164.00,111.00,25.00,25.00,176.50,123.50
|
||||
164.00,95.00,25.00,25.00,176.50,107.50
|
After Width: | Height: | Size: 7.6 KiB |
|
@ -0,0 +1,70 @@
|
|||
126,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
112.00,132.00,19.00,19.00,121.50,141.50
|
||||
108.00,132.00,19.00,19.00,117.50,141.50
|
||||
108.00,132.00,19.00,19.00,117.50,141.50
|
||||
116.00,132.00,19.00,19.00,125.50,141.50
|
||||
116.00,132.00,19.00,19.00,125.50,141.50
|
||||
112.00,124.00,19.00,19.00,121.50,133.50
|
||||
112.00,116.00,19.00,19.00,121.50,125.50
|
||||
112.00,108.00,19.00,19.00,121.50,117.50
|
||||
112.00,100.00,19.00,19.00,121.50,109.50
|
||||
100.00,100.00,19.00,19.00,109.50,109.50
|
||||
96.00,100.00,19.00,19.00,105.50,109.50
|
||||
92.00,100.00,19.00,19.00,101.50,109.50
|
||||
96.00,96.00,19.00,19.00,105.50,105.50
|
||||
92.00,96.00,19.00,19.00,101.50,105.50
|
||||
88.00,96.00,19.00,19.00,97.50,105.50
|
||||
80.00,88.00,19.00,19.00,89.50,97.50
|
||||
84.00,84.00,19.00,19.00,93.50,93.50
|
||||
92.00,84.00,19.00,19.00,101.50,93.50
|
||||
96.00,88.00,19.00,19.00,105.50,97.50
|
||||
104.00,88.00,19.00,19.00,113.50,97.50
|
||||
124.00,104.00,19.00,19.00,133.50,113.50
|
||||
132.00,104.00,19.00,19.00,141.50,113.50
|
||||
136.00,104.00,19.00,19.00,145.50,113.50
|
||||
128.00,104.00,19.00,19.00,137.50,113.50
|
||||
132.00,104.00,19.00,19.00,141.50,113.50
|
||||
136.00,104.00,19.00,19.00,145.50,113.50
|
||||
148.00,96.00,19.00,19.00,157.50,105.50
|
||||
144.00,92.00,19.00,19.00,153.50,101.50
|
||||
136.00,92.00,19.00,19.00,145.50,101.50
|
||||
128.00,92.00,19.00,19.00,137.50,101.50
|
||||
120.00,92.00,19.00,19.00,129.50,101.50
|
||||
112.00,136.00,19.00,19.00,121.50,145.50
|
||||
108.00,136.00,19.00,19.00,117.50,145.50
|
||||
100.00,136.00,19.00,19.00,109.50,145.50
|
||||
96.00,140.00,19.00,19.00,105.50,149.50
|
||||
96.00,140.00,19.00,19.00,105.50,149.50
|
||||
108.00,140.00,19.00,19.00,117.50,149.50
|
||||
112.00,140.00,19.00,19.00,121.50,149.50
|
||||
116.00,136.00,19.00,19.00,125.50,145.50
|
||||
120.00,140.00,19.00,19.00,129.50,149.50
|
||||
124.00,140.00,19.00,19.00,133.50,149.50
|
||||
120.00,140.00,19.00,19.00,129.50,149.50
|
||||
120.00,140.00,19.00,19.00,129.50,149.50
|
||||
120.00,148.00,19.00,19.00,129.50,157.50
|
||||
116.00,144.00,19.00,19.00,125.50,153.50
|
||||
116.00,152.00,19.00,19.00,125.50,161.50
|
||||
108.00,148.00,19.00,19.00,117.50,157.50
|
||||
100.00,152.00,19.00,19.00,109.50,161.50
|
||||
100.00,144.00,19.00,19.00,109.50,153.50
|
||||
96.00,148.00,19.00,19.00,105.50,157.50
|
||||
108.00,152.00,19.00,19.00,117.50,161.50
|
||||
112.00,172.00,19.00,19.00,121.50,181.50
|
||||
100.00,168.00,19.00,19.00,109.50,177.50
|
||||
92.00,164.00,19.00,19.00,101.50,173.50
|
||||
84.00,156.00,19.00,19.00,93.50,165.50
|
||||
80.00,148.00,19.00,19.00,89.50,157.50
|
||||
76.00,136.00,19.00,19.00,85.50,145.50
|
||||
76.00,124.00,19.00,19.00,85.50,133.50
|
||||
72.00,108.00,19.00,19.00,81.50,117.50
|
||||
72.00,96.00,19.00,19.00,81.50,105.50
|
||||
120.00,168.00,19.00,19.00,129.50,177.50
|
||||
128.00,160.00,19.00,19.00,137.50,169.50
|
||||
136.00,152.00,19.00,19.00,145.50,161.50
|
||||
140.00,136.00,19.00,19.00,149.50,145.50
|
||||
144.00,128.00,19.00,19.00,153.50,137.50
|
||||
148.00,120.00,19.00,19.00,157.50,129.50
|
||||
156.00,108.00,19.00,19.00,165.50,117.50
|
||||
156.00,96.00,19.00,19.00,165.50,105.50
|
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 7.6 KiB |
|
@ -0,0 +1,2 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
61.0,62.0,132.0,132.0,344,0.0,haar
|
After Width: | Height: | Size: 418 KiB |
|
@ -0,0 +1,5 @@
|
|||
x,y,dx,dy,score,angle,type
|
||||
327.0,101.0,121.0,121.0,154,0.0,lbp
|
||||
237.0,106.0,113.0,113.0,139,0.0,lbp
|
||||
164.0,49.0,91.0,91.0,49,0.0,lbp
|
||||
434.0,86.0,94.0,94.0,95,0.0,lbp
|
|
@ -0,0 +1,70 @@
|
|||
208,0
|
||||
x,y,dx,dy,x_c,y_c
|
||||
106.25,131.25,29.69,29.69,121.09,146.09
|
||||
106.25,131.25,29.69,29.69,121.09,146.09
|
||||
106.25,131.25,29.69,29.69,121.09,146.09
|
||||
112.50,131.25,29.69,29.69,127.34,146.09
|
||||
118.75,131.25,29.69,29.69,133.59,146.09
|
||||
106.25,118.75,29.69,29.69,121.09,133.59
|
||||
106.25,112.50,29.69,29.69,121.09,127.34
|
||||
106.25,100.00,29.69,29.69,121.09,114.84
|
||||
106.25,93.75,29.69,29.69,121.09,108.59
|
||||
93.75,93.75,29.69,29.69,108.59,108.59
|
||||
93.75,100.00,29.69,29.69,108.59,114.84
|
||||
87.50,100.00,29.69,29.69,102.34,114.84
|
||||
87.50,93.75,29.69,29.69,102.34,108.59
|
||||
87.50,93.75,29.69,29.69,102.34,108.59
|
||||
81.25,100.00,29.69,29.69,96.09,114.84
|
||||
68.75,87.50,29.69,29.69,83.59,102.34
|
||||
75.00,81.25,29.69,29.69,89.84,96.09
|
||||
87.50,75.00,29.69,29.69,102.34,89.84
|
||||
93.75,81.25,29.69,29.69,108.59,96.09
|
||||
100.00,81.25,29.69,29.69,114.84,96.09
|
||||
118.75,100.00,29.69,29.69,133.59,114.84
|
||||
125.00,100.00,29.69,29.69,139.84,114.84
|
||||
131.25,100.00,29.69,29.69,146.09,114.84
|
||||
125.00,93.75,29.69,29.69,139.84,108.59
|
||||
131.25,93.75,29.69,29.69,146.09,108.59
|
||||
137.50,100.00,29.69,29.69,152.34,114.84
|
||||
150.00,87.50,29.69,29.69,164.84,102.34
|
||||
143.75,81.25,29.69,29.69,158.59,96.09
|
||||
131.25,81.25,29.69,29.69,146.09,96.09
|
||||
125.00,81.25,29.69,29.69,139.84,96.09
|
||||
112.50,81.25,29.69,29.69,127.34,96.09
|
||||
106.25,137.50,29.69,29.69,121.09,152.34
|
||||
100.00,137.50,29.69,29.69,114.84,152.34
|
||||
100.00,137.50,29.69,29.69,114.84,152.34
|
||||
93.75,143.75,29.69,29.69,108.59,158.59
|
||||
93.75,143.75,29.69,29.69,108.59,158.59
|
||||
100.00,143.75,29.69,29.69,114.84,158.59
|
||||
106.25,143.75,29.69,29.69,121.09,158.59
|
||||
118.75,137.50,29.69,29.69,133.59,152.34
|
||||
125.00,137.50,29.69,29.69,139.84,152.34
|
||||
131.25,143.75,29.69,29.69,146.09,158.59
|
||||
125.00,143.75,29.69,29.69,139.84,158.59
|
||||
118.75,143.75,29.69,29.69,133.59,158.59
|
||||
125.00,150.00,29.69,29.69,139.84,164.84
|
||||
118.75,143.75,29.69,29.69,133.59,158.59
|
||||
118.75,156.25,29.69,29.69,133.59,171.09
|
||||
106.25,150.00,29.69,29.69,121.09,164.84
|
||||
100.00,156.25,29.69,29.69,114.84,171.09
|
||||
100.00,143.75,29.69,29.69,114.84,158.59
|
||||
93.75,150.00,29.69,29.69,108.59,164.84
|
||||
106.25,156.25,29.69,29.69,121.09,171.09
|
||||
112.50,181.25,29.69,29.69,127.34,196.09
|
||||
100.00,181.25,29.69,29.69,114.84,196.09
|
||||
87.50,168.75,29.69,29.69,102.34,183.59
|
||||
75.00,150.00,29.69,29.69,89.84,164.84
|
||||
68.75,137.50,29.69,29.69,83.59,152.34
|
||||
62.50,118.75,29.69,29.69,77.34,133.59
|
||||
62.50,106.25,29.69,29.69,77.34,121.09
|
||||
56.25,87.50,29.69,29.69,71.09,102.34
|
||||
56.25,75.00,29.69,29.69,71.09,89.84
|
||||
125.00,175.00,29.69,29.69,139.84,189.84
|
||||
137.50,168.75,29.69,29.69,152.34,183.59
|
||||
143.75,162.50,29.69,29.69,158.59,177.34
|
||||
150.00,150.00,29.69,29.69,164.84,164.84
|
||||
156.25,137.50,29.69,29.69,171.09,152.34
|
||||
156.25,125.00,29.69,29.69,171.09,139.84
|
||||
162.50,106.25,29.69,29.69,177.34,121.09
|
||||
162.50,93.75,29.69,29.69,177.34,108.59
|
After Width: | Height: | Size: 7.6 KiB |