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
73a34f7f
Commit
73a34f7f
authored
Sep 10, 2011
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added an overload of spatially_filter_image() that uses a separable filter.
parent
16ae5eac
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
248 additions
and
2 deletions
+248
-2
spatial_filtering.h
dlib/image_transforms/spatial_filtering.h
+109
-0
spatial_filtering_abstract.h
dlib/image_transforms/spatial_filtering_abstract.h
+49
-2
image.cpp
dlib/test/image.cpp
+90
-0
No files found.
dlib/image_transforms/spatial_filtering.h
View file @
73a34f7f
...
...
@@ -7,6 +7,7 @@
#include "spatial_filtering_abstract.h"
#include "../algs.h"
#include "../assert.h"
#include "../array2d.h"
#include <limits>
namespace
dlib
...
...
@@ -102,6 +103,114 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
in_image_type
,
typename
out_image_type
,
typename
filter_type
,
long
M
,
long
N
>
void
spatially_filter_image
(
const
in_image_type
&
in_img
,
out_image_type
&
out_img
,
const
filter_type
(
&
row_filter
)[
N
],
const
filter_type
(
&
col_filter
)[
M
],
unsigned
long
scale
=
1
,
bool
use_abs
=
false
)
{
COMPILE_TIME_ASSERT
(
pixel_traits
<
typename
in_image_type
::
type
>::
has_alpha
==
false
);
COMPILE_TIME_ASSERT
(
pixel_traits
<
typename
out_image_type
::
type
>::
has_alpha
==
false
);
COMPILE_TIME_ASSERT
(
M
%
2
==
1
);
COMPILE_TIME_ASSERT
(
N
%
2
==
1
);
DLIB_ASSERT
(
scale
>
0
,
"
\t
void spatially_filter_image()"
<<
"
\n\t
You can't give a scale of zero"
);
DLIB_ASSERT
(
is_same_object
(
in_img
,
out_img
)
==
false
,
"
\t
void spatially_filter_image()"
<<
"
\n\t
You must give two different image objects"
);
// if there isn't any input image then don't do anything
if
(
in_img
.
size
()
==
0
)
{
out_img
.
clear
();
return
;
}
out_img
.
set_size
(
in_img
.
nr
(),
in_img
.
nc
());
zero_border_pixels
(
out_img
,
M
/
2
,
N
/
2
);
// figure out the range that we should apply the filter to
const
long
first_row
=
M
/
2
;
const
long
first_col
=
N
/
2
;
const
long
last_row
=
in_img
.
nr
()
-
M
/
2
;
const
long
last_col
=
in_img
.
nc
()
-
N
/
2
;
typedef
typename
pixel_traits
<
typename
in_image_type
::
type
>::
basic_pixel_type
bp_type
;
typedef
typename
out_image_type
::
mem_manager_type
mem_manager_type
;
array2d
<
typename
promote
<
bp_type
>::
type
,
mem_manager_type
>
temp_img
;
temp_img
.
set_size
(
in_img
.
nr
(),
in_img
.
nc
());
// apply the row filter
for
(
long
r
=
0
;
r
<
in_img
.
nr
();
++
r
)
{
for
(
long
c
=
first_col
;
c
<
last_col
;
++
c
)
{
typename
promote
<
bp_type
>::
type
p
;
typename
promote
<
bp_type
>::
type
temp
=
0
;
for
(
long
n
=
0
;
n
<
N
;
++
n
)
{
// pull out the current pixel and put it into p
p
=
get_pixel_intensity
(
in_img
[
r
][
c
-
N
/
2
+
n
]);
temp
+=
p
*
row_filter
[
n
];
}
temp_img
[
r
][
c
]
=
temp
;
}
}
// apply the column filter
for
(
long
r
=
first_row
;
r
<
last_row
;
++
r
)
{
for
(
long
c
=
first_col
;
c
<
last_col
;
++
c
)
{
typename
promote
<
bp_type
>::
type
temp
=
0
;
for
(
long
m
=
0
;
m
<
M
;
++
m
)
{
temp
+=
temp_img
[
r
-
M
/
2
+
m
][
c
]
*
col_filter
[
m
];
}
temp
/=
scale
;
// Catch any underflow or apply abs as appropriate
if
(
temp
<
0
)
{
if
(
use_abs
)
{
temp
=
-
temp
;
}
else
{
temp
=
0
;
}
}
// save this pixel to the output image
assign_pixel
(
out_img
[
r
][
c
],
in_img
[
r
][
c
]);
assign_pixel_intensity
(
out_img
[
r
][
c
],
temp
);
}
}
}
// ----------------------------------------------------------------------------------------
template
<
...
...
dlib/image_transforms/spatial_filtering_abstract.h
View file @
73a34f7f
...
...
@@ -47,8 +47,55 @@ namespace dlib
- else
- pixel values after filtering that are < 0 are assigned the value of 0
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are not modified. i.e. Whatever value the border of out_img
had to begin with is what it will have after this function returns.
inside the image are set to zero.
- #out_img.nc() == in_img.nc()
- #out_img.nr() == in_img.nr()
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
in_image_type
,
typename
out_image_type
,
typename
filter_type
,
long
M
,
long
N
>
void
spatially_filter_image
(
const
in_image_type
&
in_img
,
out_image_type
&
out_img
,
const
filter_type
(
&
row_filter
)[
N
],
const
filter_type
(
&
col_filter
)[
M
],
unsigned
long
scale
=
1
,
bool
use_abs
=
false
);
/*!
requires
- in_image_type == is an implementation of array2d/array2d_kernel_abstract.h
- out_image_type == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename in_image_type::type>::has_alpha == false
- pixel_traits<typename out_image_type::type>::has_alpha == false
- is_same_object(in_img, out_img) == false
- scale > 0
- M % 2 == 1 (i.e. M must be odd)
- N % 2 == 1 (i.e. N must be odd)
ensures
- Applies the given separable spatial filter to in_img and stores the result in out_img.
Also divides each resulting pixel by scale. Calling this function has the same
effect as calling the regular spatially_filter_image() routine with a filter,
FILT, defined as follows:
- FILT[r][c] == col_filter[r]*row_filter[c]
- pixel values after filtering that are > pixel_traits<out_image_type>::max() are
set to pixel_traits<out_image_type>::max()
- if (pixel_traits<typename in_image_type::type>::grayscale == false) then
- the pixel values are converted to the HSI color space and the filtering
is done on the intensity channel only.
- if (use_abs == true) then
- pixel values after filtering that are < 0 are converted to their absolute values
- else
- pixel values after filtering that are < 0 are assigned the value of 0
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are set to zero.
- #out_img.nc() == in_img.nc()
- #out_img.nr() == in_img.nr()
!*/
...
...
dlib/test/image.cpp
View file @
73a34f7f
...
...
@@ -762,6 +762,87 @@ namespace
}
template
<
typename
T
>
void
test_filtering
(
bool
use_abs
,
unsigned
long
scale
)
{
print_spinner
();
dlog
<<
LINFO
<<
"test_filtering("
<<
use_abs
<<
","
<<
scale
<<
")"
;
array2d
<
T
>
img
,
img2
,
img3
;
img
.
set_size
(
10
,
11
);
assign_all_pixels
(
img
,
10
);
int
filter
[
3
][
3
]
=
{
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
};
assign_all_pixels
(
img2
,
3
);
spatially_filter_image
(
img
,
img2
,
filter
);
for
(
long
r
=
0
;
r
<
img2
.
nr
();
++
r
)
{
for
(
long
c
=
0
;
c
<
img2
.
nc
();
++
c
)
{
if
(
shrink_rect
(
get_rect
(
img2
),
1
).
contains
(
c
,
r
))
{
DLIB_TEST
(
img2
[
r
][
c
]
==
90
);
}
else
{
DLIB_TEST
(
img2
[
r
][
c
]
==
0
);
}
}
}
assign_all_pixels
(
img2
,
3
);
assign_all_pixels
(
img3
,
3
);
spatially_filter_image
(
img
,
img2
,
filter
);
int
row_filter
[]
=
{
1
,
1
,
1
};
int
col_filter
[]
=
{
1
,
1
,
1
};
spatially_filter_image
(
img
,
img3
,
row_filter
,
col_filter
);
DLIB_TEST
(
array_to_matrix
(
img2
)
==
array_to_matrix
(
img3
));
dlib
::
rand
rnd
;
for
(
int
i
=
0
;
i
<
30
;
++
i
)
{
for
(
long
r
=
0
;
r
<
img
.
nr
();
++
r
)
{
for
(
long
c
=
0
;
c
<
img
.
nc
();
++
c
)
{
img
[
r
][
c
]
=
rnd
.
get_random_8bit_number
();
}
}
row_filter
[
0
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
row_filter
[
1
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
row_filter
[
2
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
col_filter
[
0
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
col_filter
[
1
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
col_filter
[
2
]
=
((
int
)
rnd
.
get_random_8bit_number
()
-
100
)
/
10
;
for
(
long
rr
=
0
;
rr
<
3
;
++
rr
)
{
for
(
long
cc
=
0
;
cc
<
3
;
++
cc
)
{
filter
[
rr
][
cc
]
=
row_filter
[
cc
]
*
col_filter
[
rr
];
}
}
assign_all_pixels
(
img2
,
3
);
assign_all_pixels
(
img3
,
3
);
// Just make sure both filtering methods give the same results.
spatially_filter_image
(
img
,
img2
,
filter
,
scale
,
use_abs
);
spatially_filter_image
(
img
,
img3
,
row_filter
,
col_filter
,
scale
,
use_abs
);
DLIB_TEST
(
array_to_matrix
(
img2
)
==
array_to_matrix
(
img3
));
}
}
class
image_tester
:
public
tester
{
...
...
@@ -780,6 +861,15 @@ namespace
test_integral_image
<
double
,
int
>
();
test_integral_image
<
long
,
unsigned
char
>
();
test_integral_image
<
double
,
float
>
();
test_filtering
<
unsigned
char
>
(
false
,
1
);
test_filtering
<
unsigned
char
>
(
true
,
1
);
test_filtering
<
unsigned
char
>
(
false
,
3
);
test_filtering
<
unsigned
char
>
(
true
,
3
);
test_filtering
<
int
>
(
false
,
1
);
test_filtering
<
int
>
(
true
,
1
);
test_filtering
<
int
>
(
false
,
3
);
test_filtering
<
int
>
(
true
,
3
);
}
}
a
;
...
...
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