Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
79020cf7
Commit
79020cf7
authored
Aug 11, 2014
by
Bellaktris
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
propagation-assissted kd-tree search added, but not well debugged yet
parent
809c13bc
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
340 additions
and
123 deletions
+340
-123
structured_edge_detection.hpp
...oc/include/opencv2/ximpgroc/structured_edge_detection.hpp
+1
-1
structured_edge_detection.cpp
modules/ximpgroc/src/structured_edge_detection.cpp
+2
-2
annf.hpp
modules/xphoto/src/annf.hpp
+198
-51
inpainting.cpp
modules/xphoto/src/inpainting.cpp
+64
-58
photomontage.hpp
modules/xphoto/src/photomontage.hpp
+7
-1
whs.hpp
modules/xphoto/src/whs.hpp
+68
-10
No files found.
modules/ximpgroc/include/opencv2/ximpgroc/structured_edge_detection.hpp
View file @
79020cf7
...
...
@@ -87,7 +87,7 @@ public:
const
int
gradNum
)
const
=
0
;
};
CV_EXPORTS_W
Ptr
<
RFFeatureGetter
>
createRFFeatureGetter
(
void
);
CV_EXPORTS_W
Ptr
<
RFFeatureGetter
>
createRFFeatureGetter
();
...
...
modules/ximpgroc/src/structured_edge_detection.cpp
View file @
79020cf7
...
...
@@ -280,7 +280,7 @@ public:
* \param outNum : __rf.options.numberOfOutputChannels
* \param gradNum : __rf.options.numberOfGradientOrientations
*/
virtual
void
getFeatures
(
const
cv
::
Mat
&
src
,
Mat
&
features
,
const
int
gnrmRad
,
const
int
gsmthRad
,
virtual
void
getFeatures
(
const
Mat
&
src
,
Mat
&
features
,
const
int
gnrmRad
,
const
int
gsmthRad
,
const
int
shrink
,
const
int
outNum
,
const
int
gradNum
)
const
{
cv
::
Mat
luvImg
=
rgb2luv
(
src
);
...
...
@@ -320,7 +320,7 @@ protected:
String
name
;
};
Ptr
<
RFFeatureGetter
>
createRFFeatureGetter
(
void
)
Ptr
<
RFFeatureGetter
>
createRFFeatureGetter
()
{
return
makePtr
<
RFFeatureGetterImpl
>
();
}
...
...
modules/xphoto/src/annf.hpp
View file @
79020cf7
...
...
@@ -40,87 +40,234 @@
#ifndef __ANNF_HPP__
#define __ANNF_HPP__
#include "algo.hpp"
#include "norm2.hpp"
#include "whs.hpp"
static
void
plusToMinusUpdate
(
const
cv
::
Mat
&
current
,
cv
::
Mat
&
next
,
const
int
dx
,
const
int
dy
)
/************************* KDTree class *************************/
template
<
typename
ForwardIterator
>
void
generate_seq
(
ForwardIterator
it
,
int
first
,
int
last
)
{
for
(
int
i
=
0
;
i
<
next
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
next
.
cols
;
++
j
)
for
(
int
i
=
first
;
i
<
last
;
++
i
,
++
it
)
*
it
=
i
;
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
template
<
typename
Tp
,
int
cn
>
class
KDTree
{
private
:
class
KDTreeComparator
{
const
KDTree
<
Tp
,
cn
>
*
main
;
// main class
int
dimIdx
;
// dimension to compare
public
:
bool
operator
()
(
const
int
&
x
,
const
int
&
y
)
const
{
int
y
=
cv
::
borderInterpolate
(
i
-
dy
,
next
.
rows
,
cv
::
BORDER_CONSTANT
)
;
int
x
=
cv
::
borderInterpolate
(
j
-
dx
,
next
.
cols
,
cv
::
BORDER_CONSTANT
)
;
cv
::
Vec
<
Tp
,
cn
>
u
=
main
->
data
[
main
->
idx
[
x
]]
;
cv
::
Vec
<
Tp
,
cn
>
v
=
main
->
data
[
main
->
idx
[
y
]]
;
next
.
at
<
float
>
(
i
,
j
)
=
-
next
.
at
<
float
>
(
y
,
x
)
+
current
.
at
<
float
>
(
i
,
j
)
-
current
.
at
<
float
>
(
y
,
x
);
return
u
[
dimIdx
]
<
v
[
dimIdx
];
}
}
static
void
minusToPlusUpdate
(
const
cv
::
Mat
&
current
,
cv
::
Mat
&
next
,
const
int
dx
,
const
int
dy
)
KDTreeComparator
(
const
KDTree
<
Tp
,
cn
>
*
_main
,
int
_dimIdx
)
:
main
(
_main
),
dimIdx
(
_dimIdx
)
{}
};
const
int
leafNumber
;
int
getMaxSpreadN
(
const
int
left
,
const
int
right
)
const
;
void
operator
=
(
const
KDTree
<
Tp
,
cn
>
&
)
const
{};
public
:
std
::
vector
<
cv
::
Vec
<
Tp
,
cn
>
>
data
;
std
::
vector
<
int
>
idx
;
std
::
vector
<
cv
::
Point2i
>
nodes
;
KDTree
(
const
cv
::
Mat
&
data
,
const
int
leafNumber
=
8
);
~
KDTree
(){};
};
template
<
typename
Tp
,
int
cn
>
int
KDTree
<
Tp
,
cn
>::
getMaxSpreadN
(
const
int
_left
,
const
int
_right
)
const
{
for
(
int
i
=
0
;
i
<
next
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
next
.
cols
;
++
j
)
cv
::
Vec
<
Tp
,
cn
>
maxValue
=
data
[
idx
[
_left
]
],
minValue
=
data
[
idx
[
_left
]
];
for
(
int
i
=
_left
+
1
;
i
<
_right
;
i
+=
cn
)
for
(
int
j
=
0
;
j
<
cn
;
++
j
)
{
int
y
=
cv
::
borderInterpolate
(
i
-
dy
,
next
.
rows
,
cv
::
BORDER_CONSTANT
);
int
x
=
cv
::
borderInterpolate
(
j
-
dx
,
next
.
cols
,
cv
::
BORDER_CONSTANT
);
next
.
at
<
float
>
(
i
,
j
)
=
next
.
at
<
float
>
(
y
,
x
)
-
current
.
at
<
float
>
(
i
,
j
)
+
current
.
at
<
float
>
(
y
,
x
);
minValue
[
j
]
=
std
::
min
(
minValue
[
j
],
data
[
idx
[
i
]][
j
]
);
maxValue
[
j
]
=
std
::
max
(
maxValue
[
j
],
data
[
idx
[
i
]][
j
]
);
}
cv
::
Vec
<
Tp
,
cn
>
spread
=
maxValue
-
minValue
;
Tp
*
begIt
=
&
spread
[
0
];
return
int
(
std
::
max_element
(
begIt
,
begIt
+
cn
)
-
begIt
);
}
static
void
getWHSeries
(
const
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
const
int
nProjections
,
const
int
psize
=
8
)
template
<
typename
Tp
,
int
cn
>
KDTree
<
Tp
,
cn
>::
KDTree
(
const
cv
::
Mat
&
img
,
const
int
_leafNumber
)
:
leafNumber
(
_leafNumber
)
///////////////////////////////////////////////////
{
CV_Assert
(
nProjections
<=
psize
*
psize
&&
src
.
type
()
==
CV_32FC3
);
CV_Assert
(
hamming_length
(
psize
)
==
1
);
for
(
int
i
=
0
;
i
<
img
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
img
.
cols
;
++
j
)
data
.
push_back
(
img
.
template
at
<
cv
::
Vec
<
Tp
,
cn
>
>
(
i
,
j
));
generate_seq
(
std
::
back_inserter
(
idx
),
0
,
int
(
data
.
size
())
);
fill_n
(
std
::
back_inserter
(
nodes
),
int
(
data
.
size
()),
cv
::
Point2i
(
0
,
0
)
);
std
::
stack
<
int
>
left
,
right
;
left
.
push
(
0
);
right
.
push
(
int
(
idx
.
size
())
);
while
(
!
left
.
empty
()
)
{
int
_left
=
left
.
top
();
left
.
pop
();
int
_right
=
right
.
top
();
right
.
pop
();
std
::
vector
<
cv
::
Mat
>
projections
;
if
(
_right
-
_left
<=
leafNumber
)
{
for
(
int
i
=
_left
;
i
<
_right
;
++
i
)
{
nodes
[
idx
[
i
]].
x
=
_left
;
nodes
[
idx
[
i
]].
y
=
_right
;
}
continue
;
}
cv
::
Mat
proj
;
cv
::
boxFilter
(
proj
,
proj
,
CV_32F
,
cv
::
Size
(
psize
,
psize
),
cv
::
Point
(
-
1
,
-
1
),
false
,
cv
::
BORDER_REFLECT
);
std
::
vector
<
int
>::
iterator
begIt
=
idx
.
begin
();
int
nth
=
_left
+
(
_right
-
_left
)
/
2
;
std
::
nth_element
(
/**/
begIt
+
_left
,
begIt
+
nth
,
begIt
+
_right
,
KDTreeComparator
(
this
,
getMaxSpreadN
(
_left
,
_right
)
)
/**/
);
projections
.
push_back
(
proj
);
left
.
push
(
_left
);
right
.
push
(
nth
+
1
);
left
.
push
(
nth
+
1
);
right
.
push
(
_right
);
}
}
std
::
vector
<
int
>
snake_idx
(
1
,
0
);
std
::
vector
<
int
>
snake_idy
(
1
,
0
);
/************************** ANNF search **************************/
for
(
int
k
=
1
,
num
=
1
;
k
<
psize
&&
num
<=
nProjections
;
++
k
)
template
<
typename
Tp
,
int
cn
>
static
void
updateDist
(
const
KDTree
<
Tp
,
cn
>
&
kdTree
,
const
cv
::
Point2i
&
I
,
const
int
height
,
const
int
width
,
const
int
&
currentIdx
,
int
&
bestIdx
,
double
&
dist
)
{
for
(
int
k
=
I
.
x
;
k
<
I
.
y
;
++
k
)
{
const
int
dx
[]
=
{
(
k
%
2
==
0
)
?
+
1
:
0
,
(
k
%
2
==
0
)
?
0
:
-
1
};
const
int
dy
[]
=
{
(
k
%
2
==
0
)
?
0
:
+
1
,
(
k
%
2
==
0
)
?
-
1
:
0
};
int
newIdx
=
kdTree
.
idx
[
k
];
snake_idx
.
push_back
(
snake_idx
[
num
-
1
]
-
dx
[
1
]);
snake_idy
.
push_back
(
snake_idy
[
num
++
-
1
]
-
dy
[
1
])
;
if
(
newIdx
%
width
==
width
-
1
)
continue
;
for
(
int
i
=
0
;
i
<
k
&&
num
<
nProjections
;
++
i
,
++
num
)
if
(
newIdx
/
width
==
height
-
1
)
continue
;
int
dx
=
currentIdx
%
width
-
newIdx
%
width
;
int
dy
=
currentIdx
/
width
-
newIdx
/
width
;
if
(
abs
(
dx
)
+
abs
(
dy
)
<
32
)
continue
;
double
ndist
=
norm2
(
kdTree
.
data
[
newIdx
],
kdTree
.
data
[
currentIdx
]);
if
(
ndist
<
dist
)
{
snake_idx
.
push_back
(
snake_idx
[
num
-
1
]
+
dx
[
0
])
;
snake_idy
.
push_back
(
snake_idy
[
num
-
1
]
+
dy
[
0
])
;
dist
=
ndist
;
bestIdx
=
newIdx
;
}
}
}
static
void
getANNF
(
const
cv
::
Mat
&
img
,
std
::
vector
<
cv
::
Matx33f
>
&
transforms
,
const
int
nTransform
,
const
int
psize
)
{
/** Walsh-Hadamard Transformation **/
for
(
int
i
=
0
;
i
<
k
&&
num
<
nProjections
;
++
i
,
++
num
)
std
::
vector
<
cv
::
Mat
>
channels
;
cv
::
split
(
img
,
channels
);
const
int
np
[]
=
{
16
,
4
,
4
};
for
(
int
i
=
0
;
i
<
img
.
channels
();
++
i
)
getWHSeries
(
channels
[
i
],
channels
[
i
],
np
[
i
],
psize
);
cv
::
Mat
whs
;
// Walsh-Hadamard series
cv
::
merge
(
channels
,
whs
);
KDTree
<
float
,
24
>
kdTree
(
whs
);
std
::
vector
<
int
>
annf
(
whs
.
total
(),
0
);
/** Propagation-assisted kd-tree search **/
for
(
int
i
=
0
;
i
<
whs
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
whs
.
cols
;
++
j
)
{
snake_idx
.
push_back
(
snake_idx
[
num
-
1
]
+
dx
[
1
]);
snake_idy
.
push_back
(
snake_idy
[
num
-
1
]
+
dy
[
1
]);
double
dist
=
std
::
numeric_limits
<
double
>::
max
();
int
current
=
i
*
whs
.
cols
+
j
;
cv
::
Point2i
I
=
kdTree
.
nodes
[
i
*
whs
.
cols
+
j
];
updateDist
(
kdTree
,
I
,
whs
.
rows
,
whs
.
cols
,
current
,
annf
[
i
*
whs
.
cols
+
j
],
dist
);
if
(
i
!=
0
)
{
int
idx
=
annf
[(
i
-
1
)
*
whs
.
cols
+
j
]
+
whs
.
cols
;
cv
::
Point2i
I
=
kdTree
.
nodes
[
idx
];
updateDist
(
kdTree
,
I
,
whs
.
rows
,
whs
.
cols
,
current
,
annf
[
i
*
whs
.
cols
+
j
],
dist
);
}
if
(
j
!=
0
)
{
int
idx
=
annf
[
i
*
whs
.
cols
+
(
j
-
1
)]
+
1
;
cv
::
Point2i
I
=
kdTree
.
nodes
[
idx
];
updateDist
(
kdTree
,
I
,
whs
.
rows
,
whs
.
cols
,
current
,
annf
[
i
*
whs
.
cols
+
j
],
dist
);
}
}
}
for
(
int
i
=
1
;
i
<
nProjections
;
++
i
)
{
int
dx
=
(
snake_idx
[
i
]
-
snake_idx
[
i
-
1
]);
int
dy
=
(
snake_idy
[
i
]
-
snake_idy
[
i
-
1
]);
/** Local maxima extraction **/
cv
::
Mat_
<
double
>
annfHist
(
2
*
whs
.
rows
,
2
*
whs
.
cols
,
0.0
),
_annfHist
(
2
*
whs
.
rows
,
2
*
whs
.
cols
,
0.0
);
for
(
size_t
i
=
0
;
i
<
annf
.
size
();
++
i
)
++
annfHist
(
(
annf
[
i
]
-
int
(
i
))
/
whs
.
cols
+
whs
.
rows
,
(
annf
[
i
]
-
int
(
i
))
%
whs
.
cols
+
whs
.
cols
);
cv
::
GaussianBlur
(
annfHist
,
annfHist
,
cv
::
Size
(
9
,
9
),
1.41
,
0.0
,
cv
::
BORDER_CONSTANT
);
cv
::
dilate
(
annfHist
,
_annfHist
,
cv
::
Matx
<
uchar
,
9
,
9
>::
ones
());
dx
<<=
hamming_length
(
psize
-
1
)
-
hamming_length
(
snake_idx
[
i
-
1
]
^
snake_idx
[
i
])
;
dy
<<=
hamming_length
(
psize
-
1
)
-
hamming_length
(
snake_idy
[
i
-
1
]
^
snake_idy
[
i
])
;
std
::
vector
<
std
::
pair
<
double
,
int
>
>
amount
;
std
::
vector
<
cv
::
Point2i
>
shiftM
;
if
(
i
%
2
==
0
)
plusToMinusUpdate
(
proj
,
proj
,
dx
,
dy
);
else
minusToPlusUpdate
(
proj
,
proj
,
dx
,
dy
);
for
(
int
i
=
0
,
t
=
0
;
i
<
annfHist
.
rows
;
++
i
)
{
double
*
pAnnfHist
=
annfHist
.
template
ptr
<
double
>
(
i
);
double
*
_pAnnfHist
=
_annfHist
.
template
ptr
<
double
>
(
i
);
for
(
int
j
=
0
;
j
<
annfHist
.
cols
;
++
j
)
if
(
pAnnfHist
[
j
]
!=
0
&&
pAnnfHist
[
j
]
==
_pAnnfHist
[
j
]
)
{
amount
.
push_back
(
std
::
make_pair
(
pAnnfHist
[
j
],
t
++
)
);
shiftM
.
push_back
(
cv
::
Point2i
(
j
-
whs
.
cols
,
i
-
whs
.
rows
));
}
}
cv
::
merge
(
projections
,
dst
);
}
std
::
partial_sort
(
amount
.
begin
(),
amount
.
begin
()
+
nTransform
,
amount
.
end
(),
std
::
greater
<
std
::
pair
<
double
,
int
>
>
()
);
transforms
.
resize
(
nTransform
);
for
(
int
i
=
0
;
i
<
nTransform
;
++
i
)
{
int
idx
=
amount
[
i
].
second
;
transforms
[
i
]
=
cv
::
Matx33f
(
1
,
0
,
float
(
shiftM
[
idx
].
x
),
0
,
1
,
float
(
shiftM
[
idx
].
y
),
0
,
0
,
1
);
}
}
#endif
/* __ANNF_HPP__ */
modules/xphoto/src/inpainting.cpp
View file @
79020cf7
...
...
@@ -38,14 +38,18 @@
//M*/
#include <vector>
#include <stack>
#include <limits>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <time.h>
#include <functional>
#include "opencv2/xphoto.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core.hpp"
#include "opencv2/core/core_c.h"
...
...
@@ -67,18 +71,17 @@ namespace cv
const
int
nTransform
=
60
;
// number of dominant transforms for stitching
const
int
psize
=
8
;
// single ANNF patch size
/** ANNF computation **/
srand
(
unsigned
(
time
(
NULL
))
);
cv
::
Mat
img
;
cvtColor
(
src
,
img
,
CV_RGB2Lab
);
img
.
setTo
(
0
,
255
-
mask
);
img
.
convertTo
(
img
,
CV_32F
);
std
::
vector
<
Matx33f
>
transforms
;
// dominant transforms
for
(
int
i
=
0
;
i
<
nTransform
;
++
i
)
{
float
dx
=
float
(
rand
()
%
src
.
cols
-
src
.
cols
/
2
);
float
dy
=
float
(
rand
()
%
src
.
rows
-
src
.
rows
/
2
);
transforms
.
push_back
(
Matx33f
(
1
,
0
,
dx
,
0
,
1
,
dy
,
0
,
0
,
1
)
);
}
/** ANNF computation **/
std
::
vector
<
Matx33f
>
transforms
(
nTransform
);
xphotoInternal
::
getANNF
(
img
,
transforms
,
nTransform
,
psize
);
/** Warping **/
std
::
vector
<
Mat
>
images
(
nTransform
+
1
);
// source image transformed with transforms
...
...
@@ -87,7 +90,7 @@ namespace cv
Mat_
<
uchar
>
invMask
=
255
-
mask
;
dilate
(
invMask
,
invMask
,
Mat
(),
Point
(
-
1
,
-
1
),
2
);
src
.
convertTo
(
images
[
0
],
CV_32F
);
img
.
copyTo
(
images
[
0
]
);
mask
.
copyTo
(
masks
[
0
]
);
for
(
int
i
=
0
;
i
<
nTransform
;
++
i
)
...
...
@@ -104,7 +107,10 @@ namespace cv
Mat
photomontageResult
;
xphotoInternal
::
Photomontage
<
cv
::
Vec
<
float
,
cn
>
>
(
images
,
masks
)
.
assignResImage
(
photomontageResult
);
photomontageResult
.
convertTo
(
dst
,
dst
.
type
()
);
/** Writing result **/
photomontageResult
.
convertTo
(
photomontageResult
,
dst
.
type
()
);
cvtColor
(
photomontageResult
,
dst
,
CV_Lab2RGB
);
}
template
<
typename
Tp
,
unsigned
int
cn
>
...
...
@@ -137,66 +143,66 @@ namespace cv
switch
(
src
.
type
()
)
{
case
CV_8UC1
:
inpaint
<
uchar
,
1
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_8UC2
:
inpaint
<
uchar
,
2
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_8UC1:
//
inpaint <uchar, 1>( src, mask, dst, algorithmType );
//
break;
//
case CV_8UC2:
//
inpaint <uchar, 2>( src, mask, dst, algorithmType );
//
break;
case
CV_8UC3
:
inpaint
<
uchar
,
3
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_8UC4
:
inpaint
<
uchar
,
4
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_16SC1
:
inpaint
<
short
,
1
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_16SC2
:
inpaint
<
short
,
2
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_8UC4:
//
inpaint <uchar, 4>( src, mask, dst, algorithmType );
//
break;
//
case CV_16SC1:
//
inpaint <short, 1>( src, mask, dst, algorithmType );
//
break;
//
case CV_16SC2:
//
inpaint <short, 2>( src, mask, dst, algorithmType );
//
break;
case
CV_16SC3
:
inpaint
<
short
,
3
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_16SC4
:
inpaint
<
short
,
4
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32SC1
:
inpaint
<
int
,
1
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32SC2
:
inpaint
<
int
,
2
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_16SC4:
//
inpaint <short, 4>( src, mask, dst, algorithmType );
//
break;
//
case CV_32SC1:
//
inpaint <int, 1>( src, mask, dst, algorithmType );
//
break;
//
case CV_32SC2:
//
inpaint <int, 2>( src, mask, dst, algorithmType );
//
break;
case
CV_32SC3
:
inpaint
<
int
,
3
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32SC4
:
inpaint
<
int
,
4
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32FC1
:
inpaint
<
float
,
1
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32FC2
:
inpaint
<
float
,
2
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_32SC4:
//
inpaint <int, 4>( src, mask, dst, algorithmType );
//
break;
//
case CV_32FC1:
//
inpaint <float, 1>( src, mask, dst, algorithmType );
//
break;
//
case CV_32FC2:
//
inpaint <float, 2>( src, mask, dst, algorithmType );
//
break;
case
CV_32FC3
:
inpaint
<
float
,
3
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_32FC4
:
inpaint
<
float
,
4
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_64FC1
:
inpaint
<
double
,
1
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_64FC2
:
inpaint
<
double
,
2
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_32FC4:
//
inpaint <float, 4>( src, mask, dst, algorithmType );
//
break;
//
case CV_64FC1:
//
inpaint <double, 1>( src, mask, dst, algorithmType );
//
break;
//
case CV_64FC2:
//
inpaint <double, 2>( src, mask, dst, algorithmType );
//
break;
case
CV_64FC3
:
inpaint
<
double
,
3
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
case
CV_64FC4
:
inpaint
<
double
,
4
>
(
src
,
mask
,
dst
,
algorithmType
);
break
;
//
case CV_64FC4:
//
inpaint <double, 4>( src, mask, dst, algorithmType );
//
break;
default
:
CV_Error_
(
CV_StsNotImplemented
,
(
"Unsupported source image format (=%d)"
,
...
...
modules/xphoto/src/photomontage.hpp
View file @
79020cf7
...
...
@@ -42,11 +42,17 @@
#include "norm2.hpp"
#include "algo.hpp"
#include "gcgraph.hpp"
#define GCInfinity 10*1000*1000*1000.0
template
<
typename
Tp
>
static
int
min_idx
(
std
::
vector
<
Tp
>
vec
)
{
return
int
(
std
::
min_element
(
vec
.
begin
(),
vec
.
end
())
-
vec
.
begin
()
);
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
template
<
typename
Tp
>
class
Photomontage
{
...
...
modules/xphoto/src/
algo
.hpp
→
modules/xphoto/src/
whs
.hpp
View file @
79020cf7
...
...
@@ -37,16 +37,10 @@
//
//M*/
#ifndef __
ALGO
_HPP__
#define __
ALGO
_HPP__
#ifndef __
WHS
_HPP__
#define __
WHS
_HPP__
template
<
typename
Tp
>
static
int
min_idx
(
std
::
vector
<
Tp
>
vec
)
{
return
int
(
std
::
min_element
(
vec
.
begin
(),
vec
.
end
())
-
vec
.
begin
()
);
}
static
inline
int
hamming_length
(
int
x
)
static
inline
int
hl
(
int
x
)
{
int
res
=
0
;
while
(
x
)
...
...
@@ -57,5 +51,69 @@ static inline int hamming_length(int x)
return
res
;
}
static
void
nextProjection
(
std
::
vector
<
cv
::
Mat
>
&
projections
,
const
cv
::
Point
&
A
,
const
cv
::
Point
&
B
,
const
int
psize
)
{
int
xsign
=
(
A
.
x
!=
B
.
x
)
*
(
hl
(
A
.
x
&
B
.
x
)
+
(
B
.
x
>
A
.
x
))
&
1
;
int
ysign
=
(
A
.
y
!=
B
.
y
)
*
(
hl
(
A
.
y
&
B
.
y
)
+
(
B
.
y
>
A
.
y
))
&
1
;
bool
plusToMinusUpdate
=
std
::
max
(
xsign
,
ysign
);
int
dx
=
(
A
.
x
!=
B
.
x
)
<<
hl
(
psize
-
1
)
-
hl
(
A
.
x
^
B
.
x
);
int
dy
=
(
A
.
y
!=
B
.
y
)
<<
hl
(
psize
-
1
)
-
hl
(
A
.
y
^
B
.
y
);
cv
::
Mat
proj
=
projections
[
projections
.
size
()
-
1
];
cv
::
Mat
nproj
(
proj
.
size
(),
proj
.
type
(),
cv
::
Scalar
::
all
(
0
)
);
for
(
int
i
=
dy
;
i
<
nproj
.
rows
;
++
i
)
{
float
*
vCurrent
=
proj
.
template
ptr
<
float
>
(
i
);
float
*
vxCurrent
=
proj
.
template
ptr
<
float
>
(
i
-
dy
);
float
*
vxNext
=
nproj
.
template
ptr
<
float
>
(
i
-
dy
);
float
*
vNext
=
nproj
.
template
ptr
<
float
>
(
i
);
if
(
plusToMinusUpdate
)
for
(
int
j
=
dx
;
j
<
nproj
.
cols
;
++
j
)
vNext
[
j
]
=
-
vxNext
[
j
-
dx
]
+
vCurrent
[
j
]
-
vxCurrent
[
j
-
dx
];
else
for
(
int
j
=
dx
;
j
<
nproj
.
cols
;
++
j
)
vNext
[
j
]
=
+
vxNext
[
j
-
dx
]
+
vCurrent
[
j
]
+
vxCurrent
[
j
-
dx
];
}
projections
.
push_back
(
nproj
);
}
static
void
getWHSeries
(
const
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
const
int
nProjections
,
const
int
psize
)
{
CV_Assert
(
nProjections
<=
psize
*
psize
&&
src
.
type
()
==
CV_32FC1
);
CV_Assert
(
hl
(
psize
)
==
1
);
std
::
vector
<
cv
::
Mat
>
projections
;
cv
::
Mat
proj
;
cv
::
boxFilter
(
src
,
proj
,
CV_32F
,
cv
::
Size
(
psize
,
psize
),
cv
::
Point
(
-
1
,
-
1
),
true
,
cv
::
BORDER_REFLECT
);
projections
.
push_back
(
proj
);
std
::
vector
<
cv
::
Point2i
>
snake_idx
(
1
,
cv
::
Point2i
(
0
,
0
)
);
for
(
int
k
=
1
,
num
=
1
;
k
<
psize
&&
num
<=
nProjections
;
++
k
)
{
const
cv
::
Point2i
dv
[]
=
{
cv
::
Point2i
(
!
(
k
&
1
),
(
k
&
1
)
),
cv
::
Point2i
(
-
(
k
&
1
),
-!
(
k
&
1
)
)
};
snake_idx
.
push_back
(
snake_idx
[
num
++
-
1
]
-
dv
[
1
]);
for
(
int
i
=
0
;
i
<
k
&&
num
<
nProjections
;
++
i
)
snake_idx
.
push_back
(
snake_idx
[
num
++
-
1
]
+
dv
[
0
]);
for
(
int
i
=
0
;
i
<
k
&&
num
<
nProjections
;
++
i
)
snake_idx
.
push_back
(
snake_idx
[
num
++
-
1
]
+
dv
[
1
]);
}
for
(
int
i
=
1
;
i
<
nProjections
;
++
i
)
nextProjection
(
projections
,
snake_idx
[
i
-
1
],
snake_idx
[
i
],
psize
);
cv
::
merge
(
projections
,
dst
);
}
#endif
/* __
ALGO
_HPP__ */
#endif
/* __
WHS
_HPP__ */
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