Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
c13f46e0
Commit
c13f46e0
authored
Oct 10, 2011
by
Davis King
Browse files
Added functions for computing the convolution and cross-correlation between
two matrices.
parent
3acb55b2
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
500 additions
and
0 deletions
+500
-0
dlib/matrix.h
dlib/matrix.h
+1
-0
dlib/matrix/matrix_conv.h
dlib/matrix/matrix_conv.h
+361
-0
dlib/matrix/matrix_conv_abstract.h
dlib/matrix/matrix_conv_abstract.h
+138
-0
No files found.
dlib/matrix.h
View file @
c13f46e0
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include "matrix/matrix_assign.h"
#include "matrix/matrix_assign.h"
#include "matrix/matrix_la.h"
#include "matrix/matrix_la.h"
#include "matrix/symmetric_matrix_cache.h"
#include "matrix/symmetric_matrix_cache.h"
#include "matrix/matrix_conv.h"
#ifdef DLIB_USE_BLAS
#ifdef DLIB_USE_BLAS
#include "matrix/matrix_blas_bindings.h"
#include "matrix/matrix_blas_bindings.h"
...
...
dlib/matrix/matrix_conv.h
0 → 100644
View file @
c13f46e0
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_CONV_H__
#define DLIB_MATRIx_CONV_H__
#include "matrix_conv_abstract.h"
#include "matrix.h"
namespace
dlib
{
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
M1
,
typename
M2
,
bool
flip_m2
=
false
>
struct
op_conv
{
op_conv
(
const
M1
&
m1_
,
const
M2
&
m2_
)
:
m1
(
m1_
),
m2
(
m2_
)
{
}
const
M1
&
m1
;
const
M2
&
m2
;
const
static
long
cost
=
(
M1
::
cost
+
M2
::
cost
)
*
10
;
const
static
long
NR
=
(
M1
::
NR
*
M2
::
NR
==
0
)
?
(
0
)
:
(
M1
::
NR
+
M2
::
NR
-
1
);
const
static
long
NC
=
(
M1
::
NC
*
M2
::
NC
==
0
)
?
(
0
)
:
(
M1
::
NC
+
M2
::
NC
-
1
);
typedef
typename
M1
::
type
type
;
typedef
type
const_ret_type
;
typedef
typename
M1
::
mem_manager_type
mem_manager_type
;
typedef
typename
M1
::
layout_type
layout_type
;
const_ret_type
apply
(
long
r
,
long
c
)
const
{
type
temp
=
0
;
const
long
min_rr
=
std
::
max
<
long
>
(
r
-
m2
.
nr
()
+
1
,
0
);
const
long
max_rr
=
std
::
min
<
long
>
(
m1
.
nr
()
-
1
,
r
);
const
long
min_cc
=
std
::
max
<
long
>
(
c
-
m2
.
nc
()
+
1
,
0
);
const
long
max_cc
=
std
::
min
<
long
>
(
m1
.
nc
()
-
1
,
c
);
for
(
long
rr
=
min_rr
;
rr
<=
max_rr
;
++
rr
)
{
for
(
long
cc
=
min_cc
;
cc
<=
max_cc
;
++
cc
)
{
if
(
flip_m2
)
temp
+=
m1
(
rr
,
cc
)
*
m2
(
m2
.
nr
()
-
r
+
rr
-
1
,
m2
.
nc
()
-
c
+
cc
-
1
);
else
temp
+=
m1
(
rr
,
cc
)
*
m2
(
r
-
rr
,
c
-
cc
);
}
}
return
temp
;
}
long
nr
()
const
{
return
m1
.
nr
()
+
m2
.
nr
()
-
1
;
}
long
nc
()
const
{
return
m1
.
nc
()
+
m2
.
nc
()
-
1
;
}
template
<
typename
U
>
bool
aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
template
<
typename
U
>
bool
destructively_aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
};
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv
<
M1
,
M2
>
>
conv
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()+m2.nr()-1
- R.nc() == m1.nc()+m2.nc()-1
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv
<
M1
,
M2
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv
<
M1
,
M2
,
true
>
>
xcorr
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()+m2.nr()-1
- R.nc() == m1.nc()+m2.nc()-1
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv
<
M1
,
M2
,
true
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
M1
,
typename
M2
,
bool
flip_m2
=
false
>
struct
op_conv_same
{
op_conv_same
(
const
M1
&
m1_
,
const
M2
&
m2_
)
:
m1
(
m1_
),
m2
(
m2_
)
{
}
const
M1
&
m1
;
const
M2
&
m2
;
const
static
long
cost
=
(
M1
::
cost
+
M2
::
cost
)
*
10
;
const
static
long
NR
=
M1
::
NR
;
const
static
long
NC
=
M1
::
NC
;
typedef
typename
M1
::
type
type
;
typedef
type
const_ret_type
;
typedef
typename
M1
::
mem_manager_type
mem_manager_type
;
typedef
typename
M1
::
layout_type
layout_type
;
const_ret_type
apply
(
long
r
,
long
c
)
const
{
r
+=
m2
.
nr
()
/
2
;
c
+=
m2
.
nc
()
/
2
;
type
temp
=
0
;
const
long
min_rr
=
std
::
max
<
long
>
(
r
-
m2
.
nr
()
+
1
,
0
);
const
long
max_rr
=
std
::
min
<
long
>
(
m1
.
nr
()
-
1
,
r
);
const
long
min_cc
=
std
::
max
<
long
>
(
c
-
m2
.
nc
()
+
1
,
0
);
const
long
max_cc
=
std
::
min
<
long
>
(
m1
.
nc
()
-
1
,
c
);
for
(
long
rr
=
min_rr
;
rr
<=
max_rr
;
++
rr
)
{
for
(
long
cc
=
min_cc
;
cc
<=
max_cc
;
++
cc
)
{
if
(
flip_m2
)
temp
+=
m1
(
rr
,
cc
)
*
m2
(
m2
.
nr
()
-
r
+
rr
-
1
,
m2
.
nc
()
-
c
+
cc
-
1
);
else
temp
+=
m1
(
rr
,
cc
)
*
m2
(
r
-
rr
,
c
-
cc
);
}
}
return
temp
;
}
long
nr
()
const
{
return
m1
.
nr
();
}
long
nc
()
const
{
return
m1
.
nc
();
}
template
<
typename
U
>
bool
aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
template
<
typename
U
>
bool
destructively_aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
};
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv_same
<
M1
,
M2
>
>
conv_same
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2,'same').
In particular, this means the result will have the same dimensions as m1 and will
contain the central part of the full convolution. This means conv_same(m1,m2) is
equivalent to subm(conv(m1,m2), m2.nr()/2, m2.nc()/2, m1.nr(), m1.nc()).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()
- R.nc() == m1.nc()
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv_same
<
M1
,
M2
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv_same
<
M1
,
M2
,
true
>
>
xcorr_same
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv_same(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()
- R.nc() == m1.nc()
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv_same
<
M1
,
M2
,
true
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
M1
,
typename
M2
,
bool
flip_m2
=
false
>
struct
op_conv_valid
{
op_conv_valid
(
const
M1
&
m1_
,
const
M2
&
m2_
)
:
m1
(
m1_
),
m2
(
m2_
),
nr_
(
m1
.
nr
()
-
m2
.
nr
()
+
1
),
nc_
(
m1
.
nc
()
-
m2
.
nc
()
+
1
)
{
if
(
nr_
<
0
)
nr_
=
0
;
if
(
nc_
<
0
)
nc_
=
0
;
}
const
M1
&
m1
;
const
M2
&
m2
;
long
nr_
;
long
nc_
;
const
static
long
cost
=
(
M1
::
cost
+
M2
::
cost
)
*
10
;
const
static
long
NR
=
(
M1
::
NR
*
M2
::
NR
==
0
)
?
(
0
)
:
(
M1
::
NR
-
M2
::
NR
+
1
);
const
static
long
NC
=
(
M1
::
NC
*
M2
::
NC
==
0
)
?
(
0
)
:
(
M1
::
NC
-
M2
::
NC
+
1
);
typedef
typename
M1
::
type
type
;
typedef
type
const_ret_type
;
typedef
typename
M1
::
mem_manager_type
mem_manager_type
;
typedef
typename
M1
::
layout_type
layout_type
;
const_ret_type
apply
(
long
r
,
long
c
)
const
{
r
+=
m2
.
nr
()
-
1
;
c
+=
m2
.
nc
()
-
1
;
type
temp
=
0
;
const
long
min_rr
=
std
::
max
<
long
>
(
r
-
m2
.
nr
()
+
1
,
0
);
const
long
max_rr
=
std
::
min
<
long
>
(
m1
.
nr
()
-
1
,
r
);
const
long
min_cc
=
std
::
max
<
long
>
(
c
-
m2
.
nc
()
+
1
,
0
);
const
long
max_cc
=
std
::
min
<
long
>
(
m1
.
nc
()
-
1
,
c
);
for
(
long
rr
=
min_rr
;
rr
<=
max_rr
;
++
rr
)
{
for
(
long
cc
=
min_cc
;
cc
<=
max_cc
;
++
cc
)
{
if
(
flip_m2
)
temp
+=
m1
(
rr
,
cc
)
*
m2
(
m2
.
nr
()
-
r
+
rr
-
1
,
m2
.
nc
()
-
c
+
cc
-
1
);
else
temp
+=
m1
(
rr
,
cc
)
*
m2
(
r
-
rr
,
c
-
cc
);
}
}
return
temp
;
}
long
nr
()
const
{
return
nr_
;
}
long
nc
()
const
{
return
nc_
;
}
template
<
typename
U
>
bool
aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
template
<
typename
U
>
bool
destructively_aliases
(
const
matrix_exp
<
U
>&
item
)
const
{
return
m1
.
aliases
(
item
)
||
m2
.
aliases
(
item
);
}
};
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv_valid
<
M1
,
M2
>
>
conv_valid
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2,'valid').
In particular, this means only elements of the convolution which don't require
zero padding are included in the result.
- R::type == the same type that was in m1 and m2.
- if (m1 has larger dimensions than m2) then
- R.nr() == m1.nr()-m2.nr()+1
- R.nc() == m1.nc()-m2.nc()+1
- else
- R.nr() == 0
- R.nc() == 0
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv_valid
<
M1
,
M2
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
template
<
typename
M1
,
typename
M2
>
const
matrix_op
<
op_conv_valid
<
M1
,
M2
,
true
>
>
xcorr_valid
(
const
matrix_exp
<
M1
>&
m1
,
const
matrix_exp
<
M2
>&
m2
)
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv_valid(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- if (m1 has larger dimensions than m2) then
- R.nr() == m1.nr()-m2.nr()+1
- R.nc() == m1.nc()-m2.nc()+1
- else
- R.nr() == 0
- R.nc() == 0
!*/
{
COMPILE_TIME_ASSERT
((
is_same_type
<
typename
M1
::
type
,
typename
M2
::
type
>::
value
==
true
));
typedef
op_conv_valid
<
M1
,
M2
,
true
>
op
;
return
matrix_op
<
op
>
(
op
(
m1
.
ref
(),
m2
.
ref
()));
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_CONV_H__
dlib/matrix/matrix_conv_abstract.h
0 → 100644
View file @
c13f46e0
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_MATRIx_CONV_ABSTRACT_H__
#ifdef DLIB_MATRIx_CONV_ABSTRACT_H__
#include "matrix_abstract.h"
namespace
dlib
{
// ----------------------------------------------------------------------------------------
const
matrix_exp
conv
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()+m2.nr()-1
- R.nc() == m1.nc()+m2.nc()-1
!*/
// ----------------------------------------------------------------------------------------
const
matrix_exp
xcorr
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()+m2.nr()-1
- R.nc() == m1.nc()+m2.nc()-1
!*/
// ----------------------------------------------------------------------------------------
const
matrix_exp
conv_same
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2,'same').
In particular, this means the result will have the same dimensions as m1 and will
contain the central part of the full convolution. This means conv_same(m1,m2) is
equivalent to subm(conv(m1,m2), m2.nr()/2, m2.nc()/2, m1.nr(), m1.nc()).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()
- R.nc() == m1.nc()
!*/
// ----------------------------------------------------------------------------------------
const
matrix_exp
xcorr_same
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv_same(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- R.nr() == m1.nr()
- R.nc() == m1.nc()
!*/
// ----------------------------------------------------------------------------------------
const
matrix_exp
conv_valid
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the convolution of m1 with m2. In particular, this function is
equivalent to performing the following in matlab: R = conv2(m1,m2,'valid').
In particular, this means only elements of the convolution which don't require
zero padding are included in the result.
- R::type == the same type that was in m1 and m2.
- if (m1 has larger dimensions than m2) then
- R.nr() == m1.nr()-m2.nr()+1
- R.nc() == m1.nc()-m2.nc()+1
- else
- R.nr() == 0
- R.nc() == 0
!*/
// ----------------------------------------------------------------------------------------
const
matrix_exp
xcorr_valid
(
const
matrix_exp
&
m1
,
const
matrix_exp
&
m2
);
/*!
requires
- m1 and m2 both contain elements of the same type
ensures
- returns a matrix R such that:
- R is the cross-correlation of m1 with m2. In particular, this
function returns conv_valid(m1,flip(m2)).
- R::type == the same type that was in m1 and m2.
- if (m1 has larger dimensions than m2) then
- R.nr() == m1.nr()-m2.nr()+1
- R.nc() == m1.nc()-m2.nc()+1
- else
- R.nr() == 0
- R.nc() == 0
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_CONV_ABSTRACT_H__
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