Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
a67bdd8d
Commit
a67bdd8d
authored
7 years ago
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added point_transform_projective, find_projective_transform(), and inv() to
the Python API.
parent
a18e72e5
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
232 additions
and
1 deletion
+232
-1
vector.cpp
tools/python/src/vector.cpp
+232
-1
No files found.
tools/python/src/vector.cpp
View file @
a67bdd8d
...
...
@@ -4,7 +4,8 @@
#include "opaque_types.h"
#include <dlib/python.h>
#include <dlib/matrix.h>
#include <dlib/geometry/vector.h>
#include <dlib/geometry.h>
#include <dlib/image_transforms.h>
#include <pybind11/stl_bind.h>
#include "indexing.h"
...
...
@@ -124,6 +125,33 @@ py::tuple cv_get_matrix_size(cv& m)
// ----------------------------------------------------------------------------------------
string
point_transform_projective__repr__
(
const
point_transform_projective
&
tform
)
{
std
::
ostringstream
sout
;
sout
<<
"point_transform_projective(
\n
"
<<
csv
<<
tform
.
get_m
()
<<
")"
;
return
sout
.
str
();
}
string
point_transform_projective__str__
(
const
point_transform_projective
&
tform
)
{
std
::
ostringstream
sout
;
sout
<<
"("
<<
csv
<<
tform
.
get_m
()
<<
")"
;
return
sout
.
str
();
}
point_transform_projective
init_point_transform_projective
(
const
numpy_image
<
double
>&
m_
)
{
const_image_view
<
numpy_image
<
double
>>
m
(
m_
);
DLIB_CASSERT
(
m
.
nr
()
==
3
&&
m
.
nc
()
==
3
,
"The matrix used to construct a point_transform_projective object must be 3x3."
);
return
point_transform_projective
(
mat
(
m
));
}
// ----------------------------------------------------------------------------------------
string
point__repr__
(
const
point
&
p
)
{
std
::
ostringstream
sout
;
...
...
@@ -158,6 +186,196 @@ double dpoint_x(const dpoint& p) { return p.x(); }
double
dpoint_y
(
const
dpoint
&
p
)
{
return
p
.
y
();
}
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
dlib
::
vector
<
T
,
2
>
numpy_to_dlib_vect
(
const
py
::
array_t
<
T
>&
v
)
/*!
ensures
- converts a numpy array with 2 elements into a dlib::vector<T,2>
!*/
{
DLIB_CASSERT
(
v
.
size
()
==
2
,
"You can only convert a numpy array to a dlib point or dpoint if it has just 2 elements."
);
DLIB_CASSERT
(
v
.
ndim
()
==
1
||
v
.
ndim
()
==
2
,
"The input needs to be interpretable as a row or column vector."
);
dpoint
temp
;
if
(
v
.
ndim
()
==
1
)
{
temp
.
x
()
=
v
.
at
(
0
);
temp
.
y
()
=
v
.
at
(
1
);
}
else
if
(
v
.
shape
(
0
)
==
2
)
{
temp
.
x
()
=
v
.
at
(
0
,
0
);
temp
.
y
()
=
v
.
at
(
1
,
0
);
}
else
{
temp
.
x
()
=
v
.
at
(
0
,
0
);
temp
.
y
()
=
v
.
at
(
0
,
1
);
}
return
temp
;
}
// ----------------------------------------------------------------------------------------
point_transform_projective
py_find_projective_transform
(
const
std
::
vector
<
dpoint
>&
from_points
,
const
std
::
vector
<
dpoint
>&
to_points
)
{
DLIB_CASSERT
(
from_points
.
size
()
==
to_points
.
size
(),
"from_points and to_points must have the same number of points."
);
DLIB_CASSERT
(
from_points
.
size
()
>=
4
,
"You need at least 4 points to find a projective transform."
);
return
find_projective_transform
(
from_points
,
to_points
);
}
template
<
typename
T
>
point_transform_projective
py_find_projective_transform2
(
const
numpy_image
<
T
>&
from_points_
,
const
numpy_image
<
T
>&
to_points_
)
{
const_image_view
<
numpy_image
<
T
>>
from_points
(
from_points_
);
const_image_view
<
numpy_image
<
T
>>
to_points
(
to_points_
);
DLIB_CASSERT
(
from_points
.
nc
()
==
2
&&
to_points
.
nc
()
==
2
,
"Both from_points and to_points must be arrays with 2 columns."
);
DLIB_CASSERT
(
from_points
.
nr
()
==
to_points
.
nr
(),
"from_points and to_points must have the same number of rows."
);
DLIB_CASSERT
(
from_points
.
nr
()
>=
4
,
"You need at least 4 rows in the input matrices to find a projective transform."
);
std
::
vector
<
dpoint
>
from
,
to
;
for
(
long
r
=
0
;
r
<
from_points
.
nr
();
++
r
)
{
from
.
push_back
(
dpoint
(
from_points
[
r
][
0
],
from_points
[
r
][
1
]));
to
.
push_back
(
dpoint
(
to_points
[
r
][
0
],
to_points
[
r
][
1
]));
}
return
find_projective_transform
(
from
,
to
);
}
// ----------------------------------------------------------------------------------------
void
register_point_transform_projective
(
py
::
module
&
m
)
{
py
::
class_
<
point_transform_projective
>
(
m
,
"point_transform_projective"
,
"This is an object that takes 2D points and applies a projective transformation to them."
)
.
def
(
py
::
init
<>
(),
"ensures
\n
\
- This object will perform the identity transform. That is, given a point
\n
\
as input it will return the same point as output. Therefore, self.m == a 3x3 identity matrix."
/*!
ensures
- This object will perform the identity transform. That is, given a point
as input it will return the same point as output. Therefore, self.m == a 3x3 identity matrix.
!*/
)
.
def
(
py
::
init
<>
(
&
init_point_transform_projective
),
py
::
arg
(
"m"
),
"ensures
\n
\
- self.m == m"
)
.
def
(
"__repr__"
,
&
point_transform_projective__repr__
)
.
def
(
"__str__"
,
&
point_transform_projective__str__
)
.
def
(
"__call__"
,
[](
const
point_transform_projective
&
tform
,
const
dpoint
&
p
){
return
tform
(
p
);},
py
::
arg
(
"p"
),
"ensures
\n
\
- Applies the projective transformation defined by this object's constructor
\n
\
to p and returns the result. To define this precisely:
\n
\
- let p_h == the point p in homogeneous coordinates. That is:
\n
\
- p_h.x == p.x
\n
\
- p_h.y == p.y
\n
\
- p_h.z == 1
\n
\
- let x == m*p_h
\n
\
- Then this function returns the value x/x.z"
/*!
ensures
- Applies the projective transformation defined by this object's constructor
to p and returns the result. To define this precisely:
- let p_h == the point p in homogeneous coordinates. That is:
- p_h.x == p.x
- p_h.y == p.y
- p_h.z == 1
- let x == m*p_h
- Then this function returns the value x/x.z
!*/
)
.
def_property_readonly
(
"m"
,
[](
const
point_transform_projective
&
tform
){
numpy_image
<
double
>
tmp
;
assign_image
(
tmp
,
tform
.
get_m
());
return
tmp
;},
"m is the 3x3 matrix that defines the projective transformation."
)
.
def
(
py
::
pickle
(
&
getstate
<
point_transform_projective
>
,
&
setstate
<
point_transform_projective
>
));
m
.
def
(
"inv"
,
[](
const
point_transform_projective
&
tform
){
return
inv
(
tform
);
},
py
::
arg
(
"trans"
),
"ensures
\n
\
- If trans is an invertible transformation then this function returns a new
\n
\
transformation that is the inverse of trans. "
/*!
ensures
- If trans is an invertible transformation then this function returns a new
transformation that is the inverse of trans.
!*/
);
m
.
def
(
"find_projective_transform"
,
&
py_find_projective_transform
,
py
::
arg
(
"from_points"
),
py
::
arg
(
"to_points"
),
"requires
\n
\
- len(from_points) == len(to_points)
\n
\
- len(from_points) >= 4
\n
\
ensures
\n
\
- returns a point_transform_projective object, T, such that for all valid i:
\n
\
length(T(from_points[i]) - to_points[i])
\n
\
is minimized as often as possible. That is, this function finds the projective
\n
\
transform that maps points in from_points to points in to_points. If no
\n
\
projective transform exists which performs this mapping exactly then the one
\n
\
which minimizes the mean squared error is selected. "
/*!
requires
- len(from_points) == len(to_points)
- len(from_points) >= 4
ensures
- returns a point_transform_projective object, T, such that for all valid i:
length(T(from_points[i]) - to_points[i])
is minimized as often as possible. That is, this function finds the projective
transform that maps points in from_points to points in to_points. If no
projective transform exists which performs this mapping exactly then the one
which minimizes the mean squared error is selected.
!*/
);
const
char
*
docs
=
"requires
\n
\
- from_points and to_points have two columns and the same number of rows.
\n
\
Moreover, they have at least 4 rows.
\n
\
ensures
\n
\
- returns a point_transform_projective object, T, such that for all valid i:
\n
\
length(T(dpoint(from_points[i])) - dpoint(to_points[i]))
\n
\
is minimized as often as possible. That is, this function finds the projective
\n
\
transform that maps points in from_points to points in to_points. If no
\n
\
projective transform exists which performs this mapping exactly then the one
\n
\
which minimizes the mean squared error is selected. "
;
/*!
requires
- from_points and to_points have two columns and the same number of rows.
Moreover, they have at least 4 rows.
ensures
- returns a point_transform_projective object, T, such that for all valid i:
length(T(dpoint(from_points[i])) - dpoint(to_points[i]))
is minimized as often as possible. That is, this function finds the projective
transform that maps points in from_points to points in to_points. If no
projective transform exists which performs this mapping exactly then the one
which minimizes the mean squared error is selected.
!*/
m
.
def
(
"find_projective_transform"
,
&
py_find_projective_transform2
<
float
>
,
py
::
arg
(
"from_points"
),
py
::
arg
(
"to_points"
),
docs
);
m
.
def
(
"find_projective_transform"
,
&
py_find_projective_transform2
<
double
>
,
py
::
arg
(
"from_points"
),
py
::
arg
(
"to_points"
),
docs
);
}
// ----------------------------------------------------------------------------------------
void
bind_vector
(
py
::
module
&
m
)
{
{
...
...
@@ -182,8 +400,13 @@ void bind_vector(py::module& m)
py
::
class_
<
type
>
(
m
,
"point"
,
"This object represents a single point of integer coordinates that maps directly to a dlib::point."
)
.
def
(
py
::
init
<
long
,
long
>
(),
py
::
arg
(
"x"
),
py
::
arg
(
"y"
))
.
def
(
py
::
init
<
dpoint
>
(),
py
::
arg
(
"p"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
long
>
),
py
::
arg
(
"v"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
float
>
),
py
::
arg
(
"v"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
double
>
),
py
::
arg
(
"v"
))
.
def
(
"__repr__"
,
&
point__repr__
)
.
def
(
"__str__"
,
&
point__str__
)
.
def
(
"__sub__"
,
[](
const
point
&
a
,
const
point
&
b
){
return
a
-
b
;})
.
def
(
"__add__"
,
[](
const
point
&
a
,
const
point
&
b
){
return
a
-
b
;})
.
def
(
"normalize"
,
&
type
::
normalize
,
"Returns a unit normalized copy of this vector."
)
.
def_property
(
"x"
,
&
point_x
,
[](
point
&
p
,
long
x
){
p
.
x
()
=
x
;},
"The x-coordinate of the point."
)
.
def_property
(
"y"
,
&
point_y
,
[](
point
&
p
,
long
y
){
p
.
x
()
=
y
;},
"The y-coordinate of the point."
)
...
...
@@ -203,11 +426,16 @@ void bind_vector(py::module& m)
py
::
class_
<
type
>
(
m
,
"dpoint"
,
"This object represents a single point of floating point coordinates that maps directly to a dlib::dpoint."
)
.
def
(
py
::
init
<
double
,
double
>
(),
py
::
arg
(
"x"
),
py
::
arg
(
"y"
))
.
def
(
py
::
init
<
point
>
(),
py
::
arg
(
"p"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
long
>
),
py
::
arg
(
"v"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
float
>
),
py
::
arg
(
"v"
))
.
def
(
py
::
init
<>
(
&
numpy_to_dlib_vect
<
double
>
),
py
::
arg
(
"v"
))
.
def
(
"__repr__"
,
&
dpoint__repr__
)
.
def
(
"__str__"
,
&
dpoint__str__
)
.
def
(
"normalize"
,
&
type
::
normalize
,
"Returns a unit normalized copy of this vector."
)
.
def_property
(
"x"
,
&
dpoint_x
,
[](
dpoint
&
p
,
double
x
){
p
.
x
()
=
x
;},
"The x-coordinate of the dpoint."
)
.
def_property
(
"y"
,
&
dpoint_y
,
[](
dpoint
&
p
,
double
y
){
p
.
x
()
=
y
;},
"The y-coordinate of the dpoint."
)
.
def
(
"__sub__"
,
[](
const
dpoint
&
a
,
const
dpoint
&
b
){
return
a
-
b
;})
.
def
(
"__add__"
,
[](
const
dpoint
&
a
,
const
dpoint
&
b
){
return
a
-
b
;})
.
def
(
py
::
pickle
(
&
getstate
<
type
>
,
&
setstate
<
type
>
));
}
{
...
...
@@ -227,4 +455,7 @@ void bind_vector(py::module& m)
m
.
def
(
"dot"
,
[](
const
point
&
a
,
const
point
&
b
){
return
dot
(
a
,
b
);
},
"Returns the dot product of the points a and b."
,
py
::
arg
(
"a"
),
py
::
arg
(
"b"
));
m
.
def
(
"dot"
,
[](
const
dpoint
&
a
,
const
dpoint
&
b
){
return
dot
(
a
,
b
);
},
"Returns the dot product of the points a and b."
,
py
::
arg
(
"a"
),
py
::
arg
(
"b"
));
register_point_transform_projective
(
m
);
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment