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
ba0b4023
Commit
ba0b4023
authored
Jun 11, 2015
by
Seon-Wook Park
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply fixes suggested by Vadim
parent
508092ac
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
114 additions
and
189 deletions
+114
-189
xphoto.hpp
modules/xphoto/include/opencv2/xphoto.hpp
+1
-2
grayworld_white_balance.hpp
...xphoto/include/opencv2/xphoto/grayworld_white_balance.hpp
+0
-94
white_balance.hpp
modules/xphoto/include/opencv2/xphoto/white_balance.hpp
+32
-0
perf_grayworld.cpp
modules/xphoto/perf/perf_grayworld.cpp
+1
-1
grayworld_color_balance.cpp
modules/xphoto/samples/grayworld_color_balance.cpp
+15
-12
grayworld_white_balance.cpp
modules/xphoto/src/grayworld_white_balance.cpp
+54
-73
test_grayworld.cpp
modules/xphoto/test/test_grayworld.cpp
+11
-7
No files found.
modules/xphoto/include/opencv2/xphoto.hpp
View file @
ba0b4023
...
...
@@ -47,7 +47,6 @@
*/
#include "xphoto/inpainting.hpp"
#include "xphoto/
simple_color
_balance.hpp"
#include "xphoto/
white
_balance.hpp"
#include "xphoto/dct_image_denoising.hpp"
#include "xphoto/grayworld_white_balance.hpp"
#endif
modules/xphoto/include/opencv2/xphoto/grayworld_white_balance.hpp
deleted
100644 → 0
View file @
508092ac
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_GRAYWORLD_WHITE_BALANCE_HPP__
#define __OPENCV_GRAYWORLD_WHITE_BALANCE_HPP__
/** @file
@date Jun 3, 2015
@author Seon-Wook Park
*/
#include <opencv2/core.hpp>
namespace
cv
{
namespace
xphoto
{
//! @addtogroup xphoto
//! @{
/** @brief Implements a simple grayworld white balance algorithm.
The function autowbGrayworld scales the values of pixels based on a
gray-world assumption which states that the average of all channels
should result in a gray image.
This function adds a modification which thresholds pixels based on their
saturation value and only uses pixels below the provided threshold in
finding average pixel values.
Saturation is calculated using the following for a 3-channel RGB image per
pixel I and is in the range [0, 1]:
\f[ \texttt{Saturation} [I] = \frac{\textrm{max}(R,G,B) - \textrm{min}(R,G,B)
}{\textrm{max}(R,G,B)} \f]
A threshold of 1 means that all pixels are used to white-balance, while a
threshold of 0 means no pixels are used. Lower thresholds are useful in
white-balancing saturated images.
Currently only works on images of type @ref CV_8UC3.
@param src Input array.
@param dst Output array of the same size and type as src.
@param thresh Maximum saturation for a pixel to be included in the
gray-world assumption.
@sa balanceWhite
*/
CV_EXPORTS_W
void
autowbGrayworld
(
InputArray
src
,
OutputArray
dst
,
const
float
thresh
=
0.5
f
);
//! @}
}}
#endif // __OPENCV_GRAYWORLD_WHITE_BALANCE_HPP__
modules/xphoto/include/opencv2/xphoto/
simple_color
_balance.hpp
→
modules/xphoto/include/opencv2/xphoto/
white
_balance.hpp
View file @
ba0b4023
...
...
@@ -85,6 +85,38 @@ namespace xphoto
const
float
inputMin
=
0.0
f
,
const
float
inputMax
=
255.0
f
,
const
float
outputMin
=
0.0
f
,
const
float
outputMax
=
255.0
f
);
/** @brief Implements a simple grayworld white balance algorithm.
The function autowbGrayworld scales the values of pixels based on a
gray-world assumption which states that the average of all channels
should result in a gray image.
This function adds a modification which thresholds pixels based on their
saturation value and only uses pixels below the provided threshold in
finding average pixel values.
Saturation is calculated using the following for a 3-channel RGB image per
pixel I and is in the range [0, 1]:
\f[ \texttt{Saturation} [I] = \frac{\textrm{max}(R,G,B) - \textrm{min}(R,G,B)
}{\textrm{max}(R,G,B)} \f]
A threshold of 1 means that all pixels are used to white-balance, while a
threshold of 0 means no pixels are used. Lower thresholds are useful in
white-balancing saturated images.
Currently only works on images of type @ref CV_8UC3.
@param src Input array.
@param dst Output array of the same size and type as src.
@param thresh Maximum saturation for a pixel to be included in the
gray-world assumption.
@sa balanceWhite
*/
CV_EXPORTS_W
void
autowbGrayworld
(
InputArray
src
,
OutputArray
dst
,
float
thresh
=
0.5
f
);
//! @}
}
...
...
modules/xphoto/perf/perf_grayworld.cpp
View file @
ba0b4023
...
...
@@ -9,7 +9,7 @@ typedef perf::TestBaseWithParam<Size_WBThresh_t> Size_WBThresh;
PERF_TEST_P
(
Size_WBThresh
,
autowbGrayworld
,
testing
::
Combine
(
testing
::
Values
(
TYPICAL_MAT_SIZES
)
,
SZ_ALL_HD
,
testing
::
Values
(
0.1
,
0.5
,
1.0
)
)
)
...
...
modules/xphoto/samples/grayworld_color_balance.cpp
View file @
ba0b4023
...
...
@@ -5,6 +5,9 @@
#include "opencv2/core/utility.hpp"
using
namespace
cv
;
using
namespace
std
;
const
char
*
keys
=
{
"{i || input image name}"
...
...
@@ -14,8 +17,8 @@ const char* keys =
int
main
(
int
argc
,
const
char
**
argv
)
{
bool
printHelp
=
(
argc
==
1
);
printHelp
=
printHelp
||
(
argc
==
2
&&
st
d
::
st
ring
(
argv
[
1
])
==
"--help"
);
printHelp
=
printHelp
||
(
argc
==
2
&&
st
d
::
st
ring
(
argv
[
1
])
==
"-h"
);
printHelp
=
printHelp
||
(
argc
==
2
&&
string
(
argv
[
1
])
==
"--help"
);
printHelp
=
printHelp
||
(
argc
==
2
&&
string
(
argv
[
1
])
==
"-h"
);
if
(
printHelp
)
{
...
...
@@ -25,35 +28,35 @@ int main( int argc, const char** argv )
return
0
;
}
cv
::
CommandLineParser
parser
(
argc
,
argv
,
keys
);
CommandLineParser
parser
(
argc
,
argv
,
keys
);
if
(
!
parser
.
check
()
)
{
parser
.
printErrors
();
return
-
1
;
}
st
d
::
string
inFilename
=
parser
.
get
<
std
::
string
>
(
"i"
);
st
d
::
string
outFilename
=
parser
.
get
<
std
::
string
>
(
"o"
);
st
ring
inFilename
=
parser
.
get
<
string
>
(
"i"
);
st
ring
outFilename
=
parser
.
get
<
string
>
(
"o"
);
cv
::
Mat
src
=
cv
::
imread
(
inFilename
,
1
);
Mat
src
=
imread
(
inFilename
,
1
);
if
(
src
.
empty
()
)
{
printf
(
"Cannot read image file: %s
\n
"
,
inFilename
.
c_str
());
return
-
1
;
}
cv
::
Mat
res
(
src
.
size
(),
src
.
type
());
cv
::
xphoto
::
autowbGrayworld
(
src
,
res
);
Mat
res
(
src
.
size
(),
src
.
type
());
xphoto
::
autowbGrayworld
(
src
,
res
);
if
(
outFilename
==
""
)
{
cv
::
namedWindow
(
"after white balance"
,
1
);
cv
::
imshow
(
"after white balance"
,
res
);
namedWindow
(
"after white balance"
,
1
);
imshow
(
"after white balance"
,
res
);
cv
::
waitKey
(
0
);
waitKey
(
0
);
}
else
cv
::
imwrite
(
outFilename
,
res
);
imwrite
(
outFilename
,
res
);
return
0
;
}
modules/xphoto/src/grayworld_white_balance.cpp
View file @
ba0b4023
...
...
@@ -44,7 +44,7 @@
namespace
cv
{
namespace
xphoto
{
void
autowbGrayworld
(
InputArray
_src
,
OutputArray
_dst
,
const
float
thresh
)
void
autowbGrayworld
(
InputArray
_src
,
OutputArray
_dst
,
float
thresh
)
{
Mat
src
=
_src
.
getMat
();
...
...
@@ -57,6 +57,7 @@ namespace cv { namespace xphoto {
_dst
.
create
(
src
.
size
(),
src
.
type
());
Mat
dst
=
_dst
.
getMat
();
CV_Assert
(
dst
.
isContinuous
());
int
width
=
src
.
cols
,
height
=
src
.
rows
,
...
...
@@ -66,6 +67,7 @@ namespace cv { namespace xphoto {
// Calculate sum of pixel values of each channel
const
uchar
*
src_data
=
src
.
ptr
<
uchar
>
(
0
);
unsigned
long
sum1
=
0
,
sum2
=
0
,
sum3
=
0
;
unsigned
int
thresh255
=
round
(
thresh
*
255
);
int
i
=
0
;
#if CV_SIMD128
v_uint8x16
v_inB
,
v_inG
,
v_inR
;
...
...
@@ -73,14 +75,14 @@ namespace cv { namespace xphoto {
v_uint32x4
v_iB1
,
v_iB2
,
v_iB3
,
v_iB4
,
v_iG1
,
v_iG2
,
v_iG3
,
v_iG4
,
v_iR1
,
v_iR2
,
v_iR3
,
v_iR4
,
v_255
=
v_setall_u32
(
255
),
v_thresh
=
v_setall_u32
(
thresh255
),
v_min1
,
v_min2
,
v_min3
,
v_min4
,
v_max1
,
v_max2
,
v_max3
,
v_max4
,
v_m1
,
v_m2
,
v_m3
,
v_m4
,
v_SB
=
v_setzero_u32
(),
v_SG
=
v_setzero_u32
(),
v_SR
=
v_setzero_u32
(),
v_m1
,
v_m2
,
v_m3
,
v_m4
;
v_float32x4
v_thresh
=
v_setall_f32
(
thresh
),
v_min1
,
v_min2
,
v_min3
,
v_min4
,
v_max1
,
v_max2
,
v_max3
,
v_max4
,
v_sat1
,
v_sat2
,
v_sat3
,
v_sat4
;
v_SR
=
v_setzero_u32
();
for
(
;
i
<
N3
-
47
;
i
+=
48
)
{
...
...
@@ -102,27 +104,22 @@ namespace cv { namespace xphoto {
v_expand
(
v_s1
,
v_iR1
,
v_iR2
);
v_expand
(
v_s2
,
v_iR3
,
v_iR4
);
// Get
saturation
v_min1
=
v_
cvt_f32
(
v_reinterpret_as_s32
(
v_min
(
v_iB1
,
v_min
(
v_iG1
,
v_iR1
))
));
v_min2
=
v_
cvt_f32
(
v_reinterpret_as_s32
(
v_min
(
v_iB2
,
v_min
(
v_iG2
,
v_iR2
))
));
v_min3
=
v_
cvt_f32
(
v_reinterpret_as_s32
(
v_min
(
v_iB3
,
v_min
(
v_iG3
,
v_iR3
))
));
v_min4
=
v_
cvt_f32
(
v_reinterpret_as_s32
(
v_min
(
v_iB4
,
v_min
(
v_iG4
,
v_iR4
))
));
// Get
mins and maxs
v_min1
=
v_
min
(
v_iB1
,
v_min
(
v_iG1
,
v_iR1
));
v_min2
=
v_
min
(
v_iB2
,
v_min
(
v_iG2
,
v_iR2
));
v_min3
=
v_
min
(
v_iB3
,
v_min
(
v_iG3
,
v_iR3
));
v_min4
=
v_
min
(
v_iB4
,
v_min
(
v_iG4
,
v_iR4
));
v_max1
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_max
(
v_iB1
,
v_max
(
v_iG1
,
v_iR1
))));
v_max2
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_max
(
v_iB2
,
v_max
(
v_iG2
,
v_iR2
))));
v_max3
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_max
(
v_iB3
,
v_max
(
v_iG3
,
v_iR3
))));
v_max4
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_max
(
v_iB4
,
v_max
(
v_iG4
,
v_iR4
))));
v_sat1
=
(
v_max1
-
v_min1
)
/
v_max1
;
v_sat2
=
(
v_max2
-
v_min2
)
/
v_max2
;
v_sat3
=
(
v_max3
-
v_min3
)
/
v_max3
;
v_sat4
=
(
v_max4
-
v_min4
)
/
v_max4
;
v_max1
=
v_max
(
v_iB1
,
v_max
(
v_iG1
,
v_iR1
));
v_max2
=
v_max
(
v_iB2
,
v_max
(
v_iG2
,
v_iR2
));
v_max3
=
v_max
(
v_iB3
,
v_max
(
v_iG3
,
v_iR3
));
v_max4
=
v_max
(
v_iB4
,
v_max
(
v_iG4
,
v_iR4
));
// Calculate masks
v_m1
=
v_reinterpret_as_u32
(
v_sat1
<=
v_thresh
);
v_m2
=
v_reinterpret_as_u32
(
v_sat2
<=
v_thresh
);
v_m3
=
v_reinterpret_as_u32
(
v_sat3
<=
v_thresh
);
v_m4
=
v_reinterpret_as_u32
(
v_sat4
<=
v_thresh
);
v_m1
=
~
((
v_max1
-
v_min1
)
*
v_255
>
v_thresh
*
v_max1
);
v_m2
=
~
((
v_max2
-
v_min2
)
*
v_255
>
v_thresh
*
v_max2
);
v_m3
=
~
((
v_max3
-
v_min3
)
*
v_255
>
v_thresh
*
v_max3
);
v_m4
=
~
((
v_max4
-
v_min4
)
*
v_255
>
v_thresh
*
v_max4
);
// Apply mask
v_SB
+=
(
v_iB1
&
v_m1
)
+
(
v_iB2
&
v_m2
)
+
(
v_iB3
&
v_m3
)
+
(
v_iB4
&
v_m4
);
...
...
@@ -135,13 +132,12 @@ namespace cv { namespace xphoto {
sum2
=
v_reduce_sum
(
v_SG
);
sum3
=
v_reduce_sum
(
v_SR
);
#endif
double
minRGB
,
maxRGB
,
satur
;
unsigned
int
minRGB
,
maxRGB
;
for
(
;
i
<
N3
;
i
+=
3
)
{
minRGB
=
min
(
src_data
[
i
],
min
(
src_data
[
i
+
1
],
src_data
[
i
+
2
]));
maxRGB
=
max
(
src_data
[
i
],
max
(
src_data
[
i
+
1
],
src_data
[
i
+
2
]));
satur
=
(
maxRGB
-
minRGB
)
/
maxRGB
;
if
(
satur
>
thresh
)
continue
;
if
(
(
maxRGB
-
minRGB
)
*
255
>
thresh255
*
maxRGB
)
continue
;
sum1
+=
src_data
[
i
];
sum2
+=
src_data
[
i
+
1
];
sum3
+=
src_data
[
i
+
2
];
...
...
@@ -168,64 +164,49 @@ namespace cv { namespace xphoto {
inv3
=
(
float
)((
double
)
inv3
/
inv_max
);
}
// Fixed point arithmetic, mul by 2^8 then shift back 8 bits
unsigned
int
i_inv1
=
inv1
*
(
1
<<
8
),
i_inv2
=
inv2
*
(
1
<<
8
),
i_inv3
=
inv3
*
(
1
<<
8
);
// Scale input pixel values
uchar
*
dst_data
=
dst
.
ptr
<
uchar
>
(
0
);
i
=
0
;
#if CV_SIMD128
v_uint8x16
v_in
,
v_out
;
v_uint32x4
v_i1
,
v_i2
,
v_i3
,
v_i4
;
v_float32x4
v_f1
,
v_f2
,
v_f3
,
v_f4
,
scal1
(
inv1
,
inv2
,
inv3
,
inv1
),
scal2
(
inv2
,
inv3
,
inv1
,
inv2
),
scal3
(
inv3
,
inv1
,
inv2
,
inv3
),
scal4
(
inv1
,
inv2
,
inv3
,
0.
f
);
for
(
;
i
<
N3
-
14
;
i
+=
15
)
v_uint8x16
v_outB
,
v_outG
,
v_outR
;
v_uint16x8
v_sB1
,
v_sB2
,
v_sG1
,
v_sG2
,
v_sR1
,
v_sR2
,
v_invB
=
v_setall_u16
(
i_inv1
),
v_invG
=
v_setall_u16
(
i_inv2
),
v_invR
=
v_setall_u16
(
i_inv3
);
for
(
;
i
<
N3
-
47
;
i
+=
48
)
{
// Load 16 x 8bit uchars
v_in
=
v_load
(
&
src_data
[
i
]);
// Split into two vectors of 8 ushorts
v_expand
(
v_in
,
v_s1
,
v_s2
);
// Split into four vectors of 4 uints
v_expand
(
v_s1
,
v_i1
,
v_i2
);
v_expand
(
v_s2
,
v_i3
,
v_i4
);
v_load_deinterleave
(
&
src_data
[
i
],
v_inB
,
v_inG
,
v_inR
);
// Convert into four vectors of 4 floats
v_f1
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_i1
));
v_f2
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_i2
));
v_f3
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_i3
));
v_f4
=
v_cvt_f32
(
v_reinterpret_as_s32
(
v_i4
));
// Split into four int vectors per channel
v_expand
(
v_inB
,
v_sB1
,
v_sB2
);
v_expand
(
v_inG
,
v_sG1
,
v_sG2
);
v_expand
(
v_inR
,
v_sR1
,
v_sR2
);
// Multiply by scaling factors
v_f1
*=
scal1
;
v_f2
*=
scal2
;
v_f3
*=
scal3
;
v_f4
*=
scal4
;
// Convert back into four vectors of 4 uints
v_i1
=
v_reinterpret_as_u32
(
v_round
(
v_f1
));
v_i2
=
v_reinterpret_as_u32
(
v_round
(
v_f2
));
v_i3
=
v_reinterpret_as_u32
(
v_round
(
v_f3
));
v_i4
=
v_reinterpret_as_u32
(
v_round
(
v_f4
));
// Pack into two vectors of 8 ushorts
v_s1
=
v_pack
(
v_i1
,
v_i2
);
v_s2
=
v_pack
(
v_i3
,
v_i4
);
// Pack into vector of 16 uchars
v_out
=
v_pack
(
v_s1
,
v_s2
);
// Store
v_store
(
&
dst_data
[
i
],
v_out
);
v_sB1
=
(
v_sB1
*
v_invB
)
>>
8
;
v_sB2
=
(
v_sB2
*
v_invB
)
>>
8
;
v_sG1
=
(
v_sG1
*
v_invG
)
>>
8
;
v_sG2
=
(
v_sG2
*
v_invG
)
>>
8
;
v_sR1
=
(
v_sR1
*
v_invR
)
>>
8
;
v_sR2
=
(
v_sR2
*
v_invR
)
>>
8
;
// Pack into vectors of v_uint8x16
v_store_interleave
(
&
dst_data
[
i
],
v_pack
(
v_sB1
,
v_sB2
),
v_pack
(
v_sG1
,
v_sG2
),
v_pack
(
v_sR1
,
v_sR2
));
}
#endif
for
(
;
i
<
N3
;
i
+=
3
)
{
dst_data
[
i
+
0
]
=
(
uchar
)(
src_data
[
i
+
0
]
*
inv1
);
dst_data
[
i
+
1
]
=
(
uchar
)(
src_data
[
i
+
1
]
*
inv2
);
dst_data
[
i
+
2
]
=
(
uchar
)(
src_data
[
i
+
2
]
*
inv3
);
dst_data
[
i
]
=
(
uchar
)((
src_data
[
i
]
*
i_inv1
)
>>
8
);
dst_data
[
i
+
1
]
=
(
uchar
)(
(
src_data
[
i
+
1
]
*
i_inv2
)
>>
8
);
dst_data
[
i
+
2
]
=
(
uchar
)(
(
src_data
[
i
+
2
]
*
i_inv3
)
>>
8
);
}
}
...
...
modules/xphoto/test/test_grayworld.cpp
View file @
ba0b4023
...
...
@@ -4,7 +4,7 @@ namespace cvtest {
using
namespace
cv
;
void
ref_autowbGrayworld
(
InputArray
_src
,
OutputArray
_dst
,
const
float
thresh
)
void
ref_autowbGrayworld
(
InputArray
_src
,
OutputArray
_dst
,
float
thresh
)
{
Mat
src
=
_src
.
getMat
();
...
...
@@ -20,13 +20,12 @@ namespace cvtest {
const
uchar
*
src_data
=
src
.
ptr
<
uchar
>
(
0
);
unsigned
long
sum1
=
0
,
sum2
=
0
,
sum3
=
0
;
int
i
=
0
;
double
minRGB
,
maxRGB
,
satur
;
unsigned
int
minRGB
,
maxRGB
,
thresh255
=
round
(
thresh
*
255
)
;
for
(
;
i
<
N3
;
i
+=
3
)
{
minRGB
=
std
::
min
(
src_data
[
i
],
std
::
min
(
src_data
[
i
+
1
],
src_data
[
i
+
2
]));
maxRGB
=
std
::
max
(
src_data
[
i
],
std
::
max
(
src_data
[
i
+
1
],
src_data
[
i
+
2
]));
satur
=
(
maxRGB
-
minRGB
)
/
maxRGB
;
if
(
satur
>
thresh
)
continue
;
if
(
(
maxRGB
-
minRGB
)
*
255
>
thresh255
*
maxRGB
)
continue
;
sum1
+=
src_data
[
i
];
sum2
+=
src_data
[
i
+
1
];
sum3
+=
src_data
[
i
+
2
];
...
...
@@ -48,14 +47,19 @@ namespace cvtest {
inv3
=
(
double
)
inv3
/
inv_max
;
}
// Fixed point arithmetic, mul by 2^8 then shift back 8 bits
unsigned
int
i_inv1
=
inv1
*
(
1
<<
8
),
i_inv2
=
inv2
*
(
1
<<
8
),
i_inv3
=
inv3
*
(
1
<<
8
);
// Scale input pixel values
uchar
*
dst_data
=
dst
.
ptr
<
uchar
>
(
0
);
i
=
0
;
for
(
;
i
<
N3
;
i
+=
3
)
{
dst_data
[
i
]
=
(
uchar
)(
src_data
[
i
]
*
inv1
);
dst_data
[
i
+
1
]
=
(
uchar
)(
src_data
[
i
+
1
]
*
inv2
);
dst_data
[
i
+
2
]
=
(
uchar
)(
src_data
[
i
+
2
]
*
inv3
);
dst_data
[
i
]
=
(
uchar
)(
(
src_data
[
i
]
*
i_inv1
)
>>
8
);
dst_data
[
i
+
1
]
=
(
uchar
)(
(
src_data
[
i
+
1
]
*
i_inv2
)
>>
8
);
dst_data
[
i
+
2
]
=
(
uchar
)(
(
src_data
[
i
+
2
]
*
i_inv3
)
>>
8
);
}
}
...
...
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