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
7e7d8e90
Commit
7e7d8e90
authored
May 19, 2018
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added python interface to threshold_image() and partition_pixels().
parent
27dbbe2d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
124 additions
and
2 deletions
+124
-2
image.cpp
tools/python/src/image.cpp
+107
-0
test_numpy_returns.py
tools/python/test/test_numpy_returns.py
+17
-2
No files found.
tools/python/src/image.cpp
View file @
7e7d8e90
...
...
@@ -26,6 +26,62 @@ string print_rgb_pixel_repr(const rgb_pixel& p)
return
sout
.
str
();
}
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
numpy_image
<
unsigned
char
>
py_threshold_image2
(
const
numpy_image
<
T
>&
in_img
,
typename
pixel_traits
<
T
>::
basic_pixel_type
thresh
)
{
numpy_image
<
unsigned
char
>
out_img
;
threshold_image
(
in_img
,
out_img
);
return
out_img
;
}
template
<
typename
T
>
numpy_image
<
unsigned
char
>
py_threshold_image
(
const
numpy_image
<
T
>&
in_img
)
{
numpy_image
<
unsigned
char
>
out_img
;
threshold_image
(
in_img
,
out_img
);
return
out_img
;
}
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
typename
pixel_traits
<
T
>::
basic_pixel_type
py_partition_pixels
(
const
numpy_image
<
T
>&
img
)
{
return
partition_pixels
(
img
);
}
template
<
typename
T
>
py
::
tuple
py_partition_pixels2
(
const
numpy_image
<
T
>&
img
,
int
num_thresholds
)
{
DLIB_CASSERT
(
1
<=
num_thresholds
&&
num_thresholds
<=
6
);
typename
pixel_traits
<
T
>::
basic_pixel_type
t1
,
t2
,
t3
,
t4
,
t5
,
t6
;
switch
(
num_thresholds
)
{
case
1
:
partition_pixels
(
img
,
t1
);
return
py
::
make_tuple
(
t1
);
case
2
:
partition_pixels
(
img
,
t1
,
t2
);
return
py
::
make_tuple
(
t1
,
t2
);
case
3
:
partition_pixels
(
img
,
t1
,
t2
,
t3
);
return
py
::
make_tuple
(
t1
,
t2
,
t3
);
case
4
:
partition_pixels
(
img
,
t1
,
t2
,
t3
,
t4
);
return
py
::
make_tuple
(
t1
,
t2
,
t3
,
t4
);
case
5
:
partition_pixels
(
img
,
t1
,
t2
,
t3
,
t4
,
t5
);
return
py
::
make_tuple
(
t1
,
t2
,
t3
,
t4
,
t5
);
case
6
:
partition_pixels
(
img
,
t1
,
t2
,
t3
,
t4
,
t5
,
t6
);
return
py
::
make_tuple
(
t1
,
t2
,
t3
,
t4
,
t5
,
t6
);
}
DLIB_CASSERT
(
false
,
"This should never happen."
);
}
// ----------------------------------------------------------------------------------------
void
bind_image_classes
(
py
::
module
&
m
)
...
...
@@ -37,4 +93,55 @@ void bind_image_classes(py::module& m)
.
def_readwrite
(
"red"
,
&
rgb_pixel
::
red
)
.
def_readwrite
(
"green"
,
&
rgb_pixel
::
green
)
.
def_readwrite
(
"blue"
,
&
rgb_pixel
::
blue
);
const
char
*
docs
=
"Thresholds img and returns the result. Pixels in img with grayscale values >= partition_pixels(img)
\n
"
"have an output value of 255 and all others have a value of 0."
;
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
unsigned
char
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
uint16_t
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
uint32_t
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
float
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
double
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image
<
rgb_pixel
>
,
docs
,
py
::
arg
(
"img"
)
);
docs
=
"Thresholds img and returns the result. Pixels in img with grayscale values >= thresh
\n
"
"have an output value of 255 and all others have a value of 0."
;
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
unsigned
char
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
uint16_t
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
uint32_t
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
float
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
double
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
m
.
def
(
"threshold_image"
,
&
py_threshold_image2
<
rgb_pixel
>
,
docs
,
py
::
arg
(
"img"
),
py
::
arg
(
"thresh"
)
);
docs
=
"Finds a threshold value that would be reasonable to use with
\n
\
threshold_image(img, threshold). It does this by finding the threshold that
\n
\
partitions the pixels in img into two groups such that the sum of absolute
\n
\
deviations between each pixel and the mean of its group is minimized."
;
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
rgb_pixel
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
unsigned
char
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
uint16_t
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
uint32_t
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
float
>
,
py
::
arg
(
"img"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels
<
double
>
,
docs
,
py
::
arg
(
"img"
)
);
docs
=
"This version of partition_pixels() finds multiple partitions rather than just
\n
\
one partition. It does this by first partitioning the pixels just as the
\n
\
above partition_pixels(img) does. Then it forms a new image with only pixels
\n
\
>= that first partition value and recursively partitions this new image.
\n
\
However, the recursion is implemented in an efficient way which is faster than
\n
\
explicitly forming these images and calling partition_pixels(), but the
\n
\
output is the same as if you did. For example, suppose you called
\n
\
[t1,t2,t2] = partition_pixels(img). Then we would have:
\n
\
- t1 == partition_pixels(img)
\n
\
- t2 == partition_pixels(an image with only pixels with values >= t1 in it)
\n
\
- t3 == partition_pixels(an image with only pixels with values >= t2 in it)"
;
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
rgb_pixel
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
unsigned
char
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
uint16_t
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
uint32_t
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
float
>
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
m
.
def
(
"partition_pixels"
,
&
py_partition_pixels2
<
double
>
,
docs
,
py
::
arg
(
"img"
),
py
::
arg
(
"num_thresholds"
)
);
}
tools/python/test/test_numpy_returns.py
View file @
7e7d8e90
...
...
@@ -26,6 +26,22 @@ def get_test_face_chip():
rgb_img
,
shape
=
get_test_image_and_shape
()
return
dlib
.
get_face_chip
(
rgb_img
,
shape
)
def
test_partition_pixels
():
truth
=
(
102
,
159
,
181
);
img
,
shape
=
get_test_image_and_shape
()
assert
(
dlib
.
partition_pixels
(
img
)
==
truth
[
0
])
assert
(
dlib
.
partition_pixels
(
img
,
3
)
==
truth
)
# Call all these versions of this mainly to make sure binding to
# various image types works.
assert
(
dlib
.
partition_pixels
(
img
[:,:,
0
])
==
125
)
assert
(
dlib
.
partition_pixels
(
img
[:,:,
0
]
.
astype
(
'float32'
))
==
125
)
assert
(
dlib
.
partition_pixels
(
img
[:,:,
0
]
.
astype
(
'float64'
))
==
125
)
assert
(
dlib
.
partition_pixels
(
img
[:,:,
0
]
.
astype
(
'uint16'
))
==
125
)
assert
(
dlib
.
partition_pixels
(
img
[:,:,
0
]
.
astype
(
'uint32'
))
==
125
)
# The tests below will be skipped if Numpy is not installed
@pytest.mark.skipif
(
not
utils
.
is_numpy_installed
(),
reason
=
"requires numpy"
)
def
test_get_face_chip
():
...
...
@@ -63,4 +79,4 @@ def test_regression_issue_1220_get_face_chips():
count
=
sys
.
getrefcount
(
face_chips
)
assert
count
==
2
count
=
sys
.
getrefcount
(
face_chips
[
0
])
assert
count
==
2
\ No newline at end of file
assert
count
==
2
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