Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
3c218717
Commit
3c218717
authored
Aug 06, 2013
by
Alexander Shishkov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/f-morozov/opencv
parents
c4fb0e9d
bef8d819
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
157 additions
and
91 deletions
+157
-91
grfmt_hdr.cpp
modules/highgui/src/grfmt_hdr.cpp
+10
-3
hdr_imaging.rst
modules/photo/doc/hdr_imaging.rst
+2
-2
photo.hpp
modules/photo/include/opencv2/photo.hpp
+3
-0
calibrate.cpp
modules/photo/src/calibrate.cpp
+22
-8
hdr_common.cpp
modules/photo/src/hdr_common.cpp
+2
-4
merge.cpp
modules/photo/src/merge.cpp
+110
-66
tonemap.cpp
modules/photo/src/tonemap.cpp
+3
-3
test_hdr.cpp
modules/photo/test/test_hdr.cpp
+5
-5
No files found.
modules/highgui/src/grfmt_hdr.cpp
View file @
3c218717
...
...
@@ -90,6 +90,7 @@ bool HdrDecoder::readData(Mat& _img)
}
RGBE_ReadPixels_RLE
(
file
,
const_cast
<
float
*>
(
img
.
ptr
<
float
>
()),
img
.
cols
,
img
.
rows
);
fclose
(
file
);
file
=
NULL
;
if
(
_img
.
depth
()
==
img
.
depth
())
{
img
.
convertTo
(
_img
,
_img
.
type
());
}
else
{
...
...
@@ -123,10 +124,16 @@ HdrEncoder::~HdrEncoder()
bool
HdrEncoder
::
write
(
const
Mat
&
_img
,
const
std
::
vector
<
int
>&
params
)
{
CV_Assert
(
_img
.
channels
()
==
3
);
Mat
img
;
if
(
_img
.
depth
()
!=
CV_32F
)
{
_img
.
convertTo
(
img
,
CV_32FC3
,
1
/
255.0
f
);
CV_Assert
(
img
.
channels
()
==
3
||
img
.
channels
()
==
1
);
if
(
img
.
channels
()
==
1
)
{
std
::
vector
<
Mat
>
splitted
(
3
,
_img
);
merge
(
splitted
,
img
);
}
else
{
_img
.
copyTo
(
img
);
}
if
(
img
.
depth
()
!=
CV_32F
)
{
img
.
convertTo
(
img
,
CV_32FC3
,
1
/
255.0
f
);
}
CV_Assert
(
params
.
empty
()
||
params
[
0
]
==
HDR_NONE
||
params
[
0
]
==
HDR_RLE
);
FILE
*
fout
=
fopen
(
m_filename
.
c_str
(),
"wb"
);
...
...
modules/photo/doc/hdr_imaging.rst
View file @
3c218717
...
...
@@ -194,7 +194,7 @@ Recovers camera response.
:param src: vector of input images
:param dst: matrix with calculated camera response
, one column per channel
:param dst: matrix with calculated camera response
:param times: vector of exposure time values for each image
...
...
@@ -232,7 +232,7 @@ Merges images.
:param times: vector of exposure time values for each image
:param response:
matrix with camera response, one column per channel
:param response:
one-column matrix with camera response
MergeDebevec
--------
...
...
modules/photo/include/opencv2/photo.hpp
View file @
3c218717
...
...
@@ -206,6 +206,9 @@ public:
CV_WRAP
virtual
int
getSamples
()
const
=
0
;
CV_WRAP
virtual
void
setSamples
(
int
samples
)
=
0
;
CV_WRAP
virtual
bool
getTest
()
const
=
0
;
CV_WRAP
virtual
void
setTest
(
bool
val
)
=
0
;
};
CV_EXPORTS_W
Ptr
<
CalibrateDebevec
>
createCalibrateDebevec
(
int
samples
=
50
,
float
lambda
=
10.0
f
);
...
...
modules/photo/src/calibrate.cpp
View file @
3c218717
...
...
@@ -55,7 +55,8 @@ public:
samples
(
samples
),
lambda
(
lambda
),
name
(
"CalibrateDebevec"
),
w
(
tringleWeights
())
w
(
tringleWeights
()),
test
(
false
)
{
}
...
...
@@ -63,14 +64,19 @@ public:
{
std
::
vector
<
Mat
>
images
;
src
.
getMatVector
(
images
);
dst
.
create
(
256
,
images
[
0
].
channels
(),
CV_32F
);
Mat
response
=
dst
.
getMat
();
CV_Assert
(
!
images
.
empty
()
&&
images
.
size
()
==
times
.
size
());
CV_Assert
(
images
[
0
].
depth
()
==
CV_8U
);
CV_Assert
(
images
.
size
()
==
times
.
size
());
checkImageDimensions
(
images
);
CV_Assert
(
images
[
0
].
depth
()
==
CV_8U
);
int
channels
=
images
[
0
].
channels
();
int
CV_32FCC
=
CV_MAKETYPE
(
CV_32F
,
channels
);
for
(
int
channel
=
0
;
channel
<
images
[
0
].
channels
();
channel
++
)
{
dst
.
create
(
256
,
1
,
CV_32FCC
);
Mat
result
=
dst
.
getMat
();
std
::
vector
<
Mat
>
result_split
(
channels
);
for
(
int
channel
=
0
;
channel
<
channels
;
channel
++
)
{
Mat
A
=
Mat
::
zeros
(
samples
*
images
.
size
()
+
257
,
256
+
samples
,
CV_32F
);
Mat
B
=
Mat
::
zeros
(
A
.
rows
,
1
,
CV_32F
);
...
...
@@ -78,6 +84,9 @@ public:
for
(
int
i
=
0
;
i
<
samples
;
i
++
)
{
int
pos
=
3
*
(
rand
()
%
images
[
0
].
total
())
+
channel
;
if
(
test
)
{
pos
=
3
*
i
+
channel
;
}
for
(
size_t
j
=
0
;
j
<
images
.
size
();
j
++
)
{
int
val
=
(
images
[
j
].
ptr
()
+
pos
)[
0
];
...
...
@@ -98,11 +107,15 @@ public:
}
Mat
solution
;
solve
(
A
,
B
,
solution
,
DECOMP_SVD
);
solution
.
rowRange
(
0
,
256
).
copyTo
(
res
ponse
.
col
(
channel
)
);
solution
.
rowRange
(
0
,
256
).
copyTo
(
res
ult_split
[
channel
]
);
}
exp
(
response
,
response
);
merge
(
result_split
,
result
);
exp
(
result
,
result
);
}
bool
getTest
()
const
{
return
test
;
}
void
setTest
(
bool
val
)
{
test
=
val
;
}
int
getSamples
()
const
{
return
samples
;
}
void
setSamples
(
int
val
)
{
samples
=
val
;
}
...
...
@@ -128,6 +141,7 @@ protected:
String
name
;
int
samples
;
float
lambda
;
bool
test
;
Mat
w
;
};
...
...
modules/photo/src/hdr_common.cpp
View file @
3c218717
...
...
@@ -61,11 +61,9 @@ void checkImageDimensions(const std::vector<Mat>& images)
Mat
tringleWeights
()
{
Mat
w
(
256
,
3
,
CV_32F
);
Mat
w
(
256
,
1
,
CV_32F
);
for
(
int
i
=
0
;
i
<
256
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
w
.
at
<
float
>
(
i
,
j
)
=
i
<
128
?
i
+
1.0
f
:
256.0
f
-
i
;
}
w
.
at
<
float
>
(
i
)
=
i
<
128
?
i
+
1.0
f
:
256.0
f
-
i
;
}
return
w
;
}
...
...
modules/photo/src/merge.cpp
View file @
3c218717
...
...
@@ -61,62 +61,87 @@ public:
{
std
::
vector
<
Mat
>
images
;
src
.
getMatVector
(
images
);
dst
.
create
(
images
[
0
].
size
(),
CV_MAKETYPE
(
CV_32F
,
images
[
0
].
channels
()));
Mat
result
=
dst
.
getMat
();
CV_Assert
(
images
.
size
()
==
times
.
size
());
CV_Assert
(
images
[
0
].
depth
()
==
CV_8U
);
checkImageDimensions
(
images
);
CV_Assert
(
images
[
0
].
depth
()
==
CV_8U
);
int
channels
=
images
[
0
].
channels
();
Size
size
=
images
[
0
].
size
();
int
CV_32FCC
=
CV_MAKETYPE
(
CV_32F
,
channels
);
dst
.
create
(
images
[
0
].
size
(),
CV_32FCC
);
Mat
result
=
dst
.
getMat
();
Mat
response
=
input_response
.
getMat
();
CV_Assert
(
response
.
rows
==
256
&&
response
.
cols
>=
images
[
0
].
channels
());
Mat
log_response
;
log
(
response
,
log_response
);
std
::
vector
<
float
>
exp_times
(
times
.
size
());
for
(
size_t
i
=
0
;
i
<
exp_times
.
size
();
i
++
)
{
exp_times
[
i
]
=
logf
(
times
[
i
]);
if
(
response
.
empty
())
{
response
=
linearResponse
(
channels
);
}
log
(
response
,
response
);
CV_Assert
(
response
.
rows
==
256
&&
response
.
cols
==
1
&&
response
.
channels
()
==
channels
);
Mat
exp_values
(
times
);
log
(
exp_values
,
exp_values
);
int
channels
=
images
[
0
].
channels
();
float
*
res_ptr
=
result
.
ptr
<
float
>
();
for
(
size_t
pos
=
0
;
pos
<
result
.
total
();
pos
++
,
res_ptr
+=
channels
)
{
result
=
Mat
::
zeros
(
size
,
CV_32FCC
);
std
::
vector
<
Mat
>
result_split
;
split
(
result
,
result_split
);
Mat
weight_sum
=
Mat
::
zeros
(
size
,
CV_32F
);
std
::
vector
<
float
>
sum
(
channels
,
0
);
float
weight_sum
=
0
;
for
(
size_t
im
=
0
;
im
<
images
.
size
();
im
++
)
{
for
(
size_t
i
=
0
;
i
<
images
.
size
();
i
++
)
{
std
::
vector
<
Mat
>
splitted
;
split
(
images
[
i
],
splitted
);
uchar
*
img_ptr
=
images
[
im
].
ptr
()
+
channels
*
pos
;
float
w
=
0
;
for
(
int
channel
=
0
;
channel
<
channels
;
channel
++
)
{
w
+=
weights
.
at
<
float
>
(
img_ptr
[
channel
]);
}
w
/=
channels
;
weight_sum
+=
w
;
for
(
int
channel
=
0
;
channel
<
channels
;
channel
++
)
{
sum
[
channel
]
+=
w
*
(
log_response
.
at
<
float
>
(
img_ptr
[
channel
],
channel
)
-
exp_times
[
im
]);
}
Mat
w
=
Mat
::
zeros
(
size
,
CV_32F
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
LUT
(
splitted
[
c
],
weights
,
splitted
[
c
]);
w
+=
splitted
[
c
];
}
for
(
int
channel
=
0
;
channel
<
channels
;
channel
++
)
{
res_ptr
[
channel
]
=
exp
(
sum
[
channel
]
/
weight_sum
);
w
/=
channels
;
Mat
response_img
;
LUT
(
images
[
i
],
response
,
response_img
);
split
(
response_img
,
splitted
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
result_split
[
c
]
+=
w
.
mul
(
splitted
[
c
]
-
exp_values
.
at
<
float
>
(
i
));
}
weight_sum
+=
w
;
}
weight_sum
=
1.0
f
/
weight_sum
;
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
result_split
[
c
]
=
result_split
[
c
].
mul
(
weight_sum
);
}
merge
(
result_split
,
result
);
exp
(
result
,
result
);
}
void
process
(
InputArrayOfArrays
src
,
OutputArray
dst
,
const
std
::
vector
<
float
>&
times
)
{
Mat
response
(
256
,
3
,
CV_32F
);
for
(
int
i
=
0
;
i
<
256
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
response
.
at
<
float
>
(
i
,
j
)
=
static_cast
<
float
>
(
max
(
i
,
1
));
}
}
process
(
src
,
dst
,
times
,
response
);
process
(
src
,
dst
,
times
,
Mat
());
}
protected
:
String
name
;
Mat
weights
;
Mat
linearResponse
(
int
channels
)
{
Mat
single_response
=
Mat
(
256
,
1
,
CV_32F
);
for
(
int
i
=
1
;
i
<
256
;
i
++
)
{
single_response
.
at
<
float
>
(
i
)
=
static_cast
<
float
>
(
i
);
}
single_response
.
at
<
float
>
(
0
)
=
static_cast
<
float
>
(
1
);
std
::
vector
<
Mat
>
splitted
(
channels
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
splitted
[
c
]
=
single_response
;
}
Mat
result
;
merge
(
splitted
,
result
);
return
result
;
}
};
Ptr
<
MergeDebevec
>
createMergeDebevec
()
...
...
@@ -146,33 +171,48 @@ public:
src
.
getMatVector
(
images
);
checkImageDimensions
(
images
);
int
channels
=
images
[
0
].
channels
();
CV_Assert
(
channels
==
1
||
channels
==
3
);
Size
size
=
images
[
0
].
size
();
int
CV_32FCC
=
CV_MAKETYPE
(
CV_32F
,
channels
);
std
::
vector
<
Mat
>
weights
(
images
.
size
());
Mat
weight_sum
=
Mat
::
zeros
(
images
[
0
].
size
(),
CV_32FC1
);
for
(
size_t
im
=
0
;
im
<
images
.
size
();
im
++
)
{
Mat
weight_sum
=
Mat
::
zeros
(
size
,
CV_32F
);
for
(
size_t
i
=
0
;
i
<
images
.
size
();
i
++
)
{
Mat
img
,
gray
,
contrast
,
saturation
,
wellexp
;
std
::
vector
<
Mat
>
channels
(
3
);
std
::
vector
<
Mat
>
splitted
(
channels
);
images
[
im
].
convertTo
(
img
,
CV_32FC3
,
1.0
/
255.0
);
cvtColor
(
img
,
gray
,
COLOR_RGB2GRAY
);
split
(
img
,
channels
);
images
[
i
].
convertTo
(
img
,
CV_32F
,
1.0
f
/
255.0
f
);
if
(
channels
==
3
)
{
cvtColor
(
img
,
gray
,
COLOR_RGB2GRAY
);
}
else
{
img
.
copyTo
(
gray
);
}
split
(
img
,
splitted
);
Laplacian
(
gray
,
contrast
,
CV_32F
);
contrast
=
abs
(
contrast
);
Mat
mean
=
(
channels
[
0
]
+
channels
[
1
]
+
channels
[
2
])
/
3.0
f
;
saturation
=
Mat
::
zeros
(
channels
[
0
].
size
(),
CV_32FC1
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
Mat
deviation
=
channels
[
i
]
-
mean
;
pow
(
deviation
,
2.0
,
deviation
);
Mat
mean
=
Mat
::
zeros
(
size
,
CV_32F
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
mean
+=
splitted
[
c
];
}
mean
/=
channels
;
saturation
=
Mat
::
zeros
(
size
,
CV_32F
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
Mat
deviation
=
splitted
[
c
]
-
mean
;
pow
(
deviation
,
2.0
f
,
deviation
);
saturation
+=
deviation
;
}
sqrt
(
saturation
,
saturation
);
wellexp
=
Mat
::
ones
(
gray
.
size
(),
CV_32FC1
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
Mat
exp
=
channels
[
i
]
-
0.5
f
;
pow
(
exp
,
2
,
exp
);
exp
=
-
exp
/
0.08
;
wellexp
=
Mat
::
ones
(
size
,
CV_32F
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
Mat
exp
=
splitted
[
c
]
-
0.5
f
;
pow
(
exp
,
2
.0
f
,
exp
);
exp
=
-
exp
/
0.08
f
;
wellexp
=
wellexp
.
mul
(
exp
);
}
...
...
@@ -180,33 +220,37 @@ public:
pow
(
saturation
,
wsat
,
saturation
);
pow
(
wellexp
,
wexp
,
wellexp
);
weights
[
im
]
=
contrast
;
weights
[
im
]
=
weights
[
im
].
mul
(
saturation
);
weights
[
im
]
=
weights
[
im
].
mul
(
wellexp
);
weight_sum
+=
weights
[
im
];
weights
[
i
]
=
contrast
;
if
(
channels
==
3
)
{
weights
[
i
]
=
weights
[
i
].
mul
(
saturation
);
}
weights
[
i
]
=
weights
[
i
].
mul
(
wellexp
);
weight_sum
+=
weights
[
i
];
}
int
maxlevel
=
static_cast
<
int
>
(
logf
(
static_cast
<
float
>
(
m
ax
(
images
[
0
].
rows
,
images
[
0
].
cols
)))
/
logf
(
2.0
))
-
1
;
int
maxlevel
=
static_cast
<
int
>
(
logf
(
static_cast
<
float
>
(
m
in
(
size
.
width
,
size
.
height
)))
/
logf
(
2.0
f
))
;
std
::
vector
<
Mat
>
res_pyr
(
maxlevel
+
1
);
for
(
size_t
i
m
=
0
;
im
<
images
.
size
();
im
++
)
{
weights
[
i
m
]
/=
weight_sum
;
for
(
size_t
i
=
0
;
i
<
images
.
size
();
i
++
)
{
weights
[
i
]
/=
weight_sum
;
Mat
img
;
images
[
im
].
convertTo
(
img
,
CV_32FC3
,
1
/
255.0
);
images
[
i
].
convertTo
(
img
,
CV_32F
,
1.0
f
/
255.0
f
);
std
::
vector
<
Mat
>
img_pyr
,
weight_pyr
;
buildPyramid
(
img
,
img_pyr
,
maxlevel
);
buildPyramid
(
weights
[
im
],
weight_pyr
,
maxlevel
);
buildPyramid
(
weights
[
i
],
weight_pyr
,
maxlevel
);
for
(
int
lvl
=
0
;
lvl
<
maxlevel
;
lvl
++
)
{
Mat
up
;
pyrUp
(
img_pyr
[
lvl
+
1
],
up
,
img_pyr
[
lvl
].
size
());
img_pyr
[
lvl
]
-=
up
;
}
for
(
int
lvl
=
0
;
lvl
<=
maxlevel
;
lvl
++
)
{
std
::
vector
<
Mat
>
channels
(
3
);
split
(
img_pyr
[
lvl
],
channels
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
channels
[
i
]
=
channels
[
i
].
mul
(
weight_pyr
[
lvl
]);
std
::
vector
<
Mat
>
splitted
(
channels
);
split
(
img_pyr
[
lvl
],
splitted
);
for
(
int
c
=
0
;
c
<
channels
;
c
++
)
{
splitted
[
c
]
=
splitted
[
c
].
mul
(
weight_pyr
[
lvl
]);
}
merge
(
channels
,
img_pyr
[
lvl
]);
merge
(
splitted
,
img_pyr
[
lvl
]);
if
(
res_pyr
[
lvl
].
empty
())
{
res_pyr
[
lvl
]
=
img_pyr
[
lvl
];
}
else
{
...
...
@@ -219,7 +263,7 @@ public:
pyrUp
(
res_pyr
[
lvl
],
up
,
res_pyr
[
lvl
-
1
].
size
());
res_pyr
[
lvl
-
1
]
+=
up
;
}
dst
.
create
(
images
[
0
].
size
(),
CV_32FC3
);
dst
.
create
(
size
,
CV_32FCC
);
res_pyr
[
0
].
copyTo
(
dst
.
getMat
());
}
...
...
modules/photo/src/tonemap.cpp
View file @
3c218717
...
...
@@ -185,7 +185,7 @@ class TonemapDurandImpl : public TonemapDurand
public
:
TonemapDurandImpl
(
float
gamma
,
float
contrast
,
float
saturation
,
float
sigma_color
,
float
sigma_space
)
:
gamma
(
gamma
),
contrast
(
contrast
),
contrast
(
contrast
),
saturation
(
saturation
),
sigma_color
(
sigma_color
),
sigma_space
(
sigma_space
),
...
...
@@ -462,8 +462,8 @@ protected:
void
signedPow
(
Mat
src
,
float
power
,
Mat
&
dst
)
{
Mat
sign
=
(
src
>
0
);
sign
.
convertTo
(
sign
,
CV_32F
,
1
/
255.0
f
);
sign
=
sign
*
2
-
1
;
sign
.
convertTo
(
sign
,
CV_32F
,
1
.0
f
/
255.0
f
);
sign
=
sign
*
2
.0
f
-
1.0
f
;
pow
(
abs
(
src
),
power
,
dst
);
dst
=
dst
.
mul
(
sign
);
}
...
...
modules/photo/test/test_hdr.cpp
View file @
3c218717
...
...
@@ -78,11 +78,11 @@ void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times = DE
void
loadResponseCSV
(
String
path
,
Mat
&
response
)
{
response
=
Mat
(
256
,
3
,
CV_32F
);
response
=
Mat
(
256
,
1
,
CV_32FC3
);
ifstream
resp_file
(
path
.
c_str
());
for
(
int
i
=
0
;
i
<
256
;
i
++
)
{
for
(
int
c
hannel
=
0
;
channel
<
3
;
channel
++
)
{
resp_file
>>
response
.
at
<
float
>
(
i
,
channel
)
;
for
(
int
c
=
0
;
c
<
3
;
c
++
)
{
resp_file
>>
response
.
at
<
Vec3f
>
(
i
)[
c
]
;
resp_file
.
ignore
(
1
);
}
}
...
...
@@ -187,6 +187,7 @@ TEST(Photo_MergeDebevec, regression)
Mat
result
,
expected
;
loadImage
(
test_path
+
"merge/debevec.exr"
,
expected
);
merge
->
process
(
images
,
result
,
times
,
response
);
imwrite
(
"test.exr"
,
result
);
checkEqual
(
expected
,
result
,
1e-3
f
);
}
...
...
@@ -199,9 +200,8 @@ TEST(Photo_CalibrateDebevec, regression)
Mat
expected
,
response
;
loadExposureSeq
(
test_path
+
"exposures/"
,
images
,
times
);
loadResponseCSV
(
test_path
+
"calibrate/debevec.csv"
,
expected
);
Ptr
<
CalibrateDebevec
>
calibrate
=
createCalibrateDebevec
();
srand
(
1
);
calibrate
->
setTest
(
true
);
calibrate
->
process
(
images
,
response
,
times
);
checkEqual
(
expected
,
response
,
1e-3
f
);
}
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