Skip to content

Commit ff44d10

Browse files
authored
feat(iba): add 'auto' value for all options of IBA::demosaic (AcademySoftwareFoundation#4786)
- The parameter 'pattern' now supports a special value 'auto', which is also default. - The parameter 'layout' now supports a special value 'auto', which is also default. - The parameter 'algorithm' now supports a special value 'auto', which is also default. - New parameter 'white_balance_mode. - The raw input plugin now adds an attribute 'raw:WhiteBalance' in addition to the libraw-specific 'raw:cam_mul', carrying the same values. This changes the current behaviour, please read below. Previously, the parameter 'pattern' defaulted to 'bayer'. The new default value of 'auto' makes OIIO look for the input ImageBuf's attribute 'raw:FilterPattern', and deduct the pattern from its value. If the attribute is missing, 'bayer' is assumed. Previously, the parameter 'layout' defaulted to 'RGGB' for Bayer pattern, or 'GRBGBR BGGRGG RGGBGG GBRGRB RGGBGG BGGRGG' for X-Trans. The new default value of 'auto' makes OIIO look for the input ImageBuf's attribute 'raw:FilterPattern', and deduct the layout from its value. If the attribute is missing, the old default values are assumed. Technically the 2 changes above the current behaviour may change, but only in a very rare use case: when the user relies on the old default values to decode the image, and there is metadata present in the ImageBuf saying that the pattern and/or layout is different from the default. Previously, the parameter 'algorithm' defaulted to 'linear'. The new default value 'auto' maps to 'MHC' for the Bayer pattern, and 'linear' for the X-Trans. The newly added parameter 'white_balance_mode' can have one of the following three values: - 'auto' (default) - the white-balancing weights are read from the input ImageBuf's attribute 'raw:WhiteBalance', defaulting to (1, 1, 1, 1). - 'manual' - the white-balancing weights are read from the parameter 'white_balance'. - 'none' - same as 'manual' with the weights of (1, 1, 1, 1). This changes the current behaviour where the white-balancing weights from the parameter 'white_balance' get applied if present. Now, in addition to providing them, you need to explicitly set 'white_balance_mode' to 'manual'. I've updated the unit tests to cover the new 'auto' mode. --------- Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
1 parent 731b90b commit ff44d10

17 files changed

Lines changed: 345 additions & 144 deletions

File tree

src/doc/imagebufalgo.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ Shuffling channels
11831183

11841184
.. code-tab:: bash oiiotool
11851185

1186-
oiiotool -iconfig raw:Demosaic none -i test.cr3 --demosaic:layout=GRBG:white_balance=2.0,0.8,1.2,1.5 -o out.exr
1186+
oiiotool -iconfig raw:Demosaic none -i test.cr3 --demosaic:layout=GRBG:white_balance_mode=manual:white_balance=2.0,0.8,1.2,1.5 -o out.exr
11871187

11881188
|
11891189

src/doc/oiiotool.rst

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4281,20 +4281,41 @@ current top image.
42814281
Optional appended modifiers include:
42824282

42834283
`pattern=` *name*
4284-
sensor pattern. Currently supported patterns: "bayer", "xtrans".
4284+
sensor pattern. Currently supported patterns: "auto"(default), "bayer",
4285+
"xtrans". In the "auto" mode the pattern is deducted from the
4286+
"raw:FilterPattern" attribute of the source image buffer, defaulting to
4287+
"bayer" if absent.
42854288
`layout=` *name*
4286-
photosite order of the specified pattern. The default value is "RGGB"
4287-
for Bayer, and "GRBGBR BGGRGG RGGBGG GBRGRB RGGBGG BGGRGG" for X-Trans.
4289+
The order the color filter array elements are arranged in,
4290+
pattern-specific. The Bayer pattern sensors usually have 4 values in the
4291+
layout string, describing the 2x2 pixels region. The X-Trans pattern
4292+
sensors have 36 values in the layout string, describing the 6x6 pixels
4293+
region (with optional whitespaces separating the rows). When set to
4294+
"auto", OIIO will try to fetch the layout from the "raw:FilterPattern"
4295+
attribute of the source image buffer, falling back to "RGGB" for Bayer,
4296+
"GRBGBR BGGRGG RGGBGG GBRGRB RGGBGG BGGRGG" for X-Trans if absent.
42884297
`algorithm=` *name*
4289-
the name of the algorithm to use.
4298+
the name of the algorithm to use, defaults to "auto".
42904299
The Bayer-pattern algorithms:
42914300
- "linear"(simple bilinear demosaicing),
4292-
- "MHC"(Malvar-He-Cutler algorithm).
4301+
- "MHC"(Malvar-He-Cutler algorithm),
4302+
- "auto"(same as "MHC").
42934303
The X-Trans-pattern algorithms:
4294-
- "linear"(simple bilinear demosaicing).
4295-
`white-balance=` *v1,v2,v3...*
4304+
- "linear"(simple bilinear demosaicing),
4305+
- "auto"(same as "linear").
4306+
`white_balance_mode=` *name*
4307+
white-balancing mode to use. The supported modes are:
4308+
- "auto"(OIIO will try to fetch the white balancing weights from the
4309+
"raw:WhiteBalance" attribute of the source image buffer, falling back to
4310+
{1.0, 1.0, 1.0, 1.0} if absent),
4311+
- "manual"(The white balancing weights will be taken from the attribute
4312+
"white-balance" (see below) if present, falling back to
4313+
{1.0, 1.0, 1.0, 1.0} if absent),
4314+
- "none"(no white balancing will be performed).
4315+
`white_balance=` *v1,v2,v3...*
42964316
optional white balance weights, can contain either three (R,G,B) or four
4297-
(R,G1,B,G2) values. The order of the white balance multipliers is as
4317+
(R,G1,B,G2) values, only used when the white-balancing mode (see above)
4318+
is set to "manual". The order of the white balance multipliers is as
42984319
specified, it does not depend on the matrix layout.
42994320

43004321
Examples::
@@ -4303,7 +4324,7 @@ current top image.
43034324
--output out.exr
43044325

43054326
oiiotool --iconfig raw:Demosaic none --input test.cr3 \
4306-
--demosaic:pattern=bayer:layout=GRBG:algorithm=MHC:white_balance=2.0,0.8,1.2,1.5 \
4327+
--demosaic:pattern=bayer:layout=GRBG:algorithm=MHC:white_balance_mode=manual:white_balance=2.0,0.8,1.2,1.5 \
43074328
--output out.exr
43084329

43094330

src/doc/pythonbindings.rst

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,17 +3718,24 @@ Color manipulation
37183718
ImageBufAlgo.unpremult (A, A)
37193719
37203720
3721-
.. py:method:: ImageBuf ImageBufAlgo.demosaic (src, pattern="", algorithm="", layout="", white_balance=py::none(), roi=ROI.All, nthreads=0)
3722-
bool ImageBufAlgo.demosaic (dst, src, pattern="", algorithm="", layout="", white_balance=py::none(), roi=ROI.All, nthreads=0)
3721+
.. py:method:: ImageBuf ImageBufAlgo.demosaic (src, pattern="", algorithm="", layout="", white_balance_mode="", white_balance=py::none(), roi=ROI.All, nthreads=0)
3722+
bool ImageBufAlgo.demosaic (dst, src, pattern="", algorithm="", layout="", white_balance_mode="", white_balance=py::none(), roi=ROI.All, nthreads=0)
37233723
Demosaic a raw digital camera image.
37243724
37253725
`demosaic` can currently process Bayer-pattern images (pattern="bayer")
37263726
using two algorithms: "linear" (simple bilinear demosaicing), and "MHC"
37273727
(Malvar-He-Cutler algorithm); or X-Trans-pattern images (pattern="xtrans")
3728-
using "linear" algorithm. The optional white_balance parameter can take
3729-
a tuple of three (R,G,B), or four (R,G1,B,G2) values. The order of the
3730-
white balance multipliers is as specified, it does not depend on the matrix
3731-
layout.
3728+
using "linear" algorithm. When "layout" or "pattern" are absent or set to
3729+
"auto" OIIO will attempt to deduct their value from the "raw:FilterPattern"
3730+
attribute of the source image buffer. White-balancing mode can be se to
3731+
"auto" (OIIO will try to fetch the white balancing weights from the
3732+
"raw:WhiteBalance" attribute of the source image buffer, falling back to
3733+
{1.0, 1.0, 1.0, 1.0} if absent), "manual" (The white balancing weights will
3734+
be taken from the attribute "white_balance" (see below) if present, falling
3735+
back to {1.0, 1.0, 1.0, 1.0} if absent), "none" (no white balancing will be
3736+
performed). The optional "white_balance" parameter can take a tuple of three
3737+
(R,G,B), or four (R,G1,B,G2) values. The order of the white balance
3738+
multipliers is as specified, it does not depend on the matrix layout.
37323739
37333740
Example:
37343741
@@ -3737,7 +3744,7 @@ Color manipulation
37373744
Src = ImageBuf("test.cr3", 0, 0, hint)
37383745
WB_RGBG = (2.0, 0.8, 1.5, 1.2)
37393746
Dst = OpenImageIO.ImageBufAlgo.demosaic(Src, layout="GRBG",
3740-
white_balance = WB_RGBG)
3747+
white_balance_mode = "manual", "white_balance = WB_RGBG)
37413748
37423749
37433750

src/include/OpenImageIO/imagebufalgo.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,28 +2162,45 @@ bool OIIO_API repremult (ImageBuf &dst, const ImageBuf &src,
21622162
/// The `options` list contains optional ParamValue's that may control the reconstruction.
21632163
/// The following options are recognized:
21642164
///
2165-
/// - "pattern" : string (default: "bayer")
2165+
/// - "pattern" : string (default: "auto")
21662166
///
21672167
/// The type of image sensor color filter array. Currently suported patterns:
21682168
/// - `bayer` - Bayer-pattern image.
21692169
/// - `xtrans` - X-Trans-pattern image.
2170+
/// - `auto` - the pattern is deducted from the "raw:FilterPattern" attribute of the source image buffer.
21702171
///
2171-
/// - "algorithm" : string (default: "linear")
2172+
/// - "algorithm" : string (default: "auto")
21722173
///
21732174
/// The demosaicing algorithm, pattern-specific.
21742175
/// The following algorithms are supported for Bayer-pattern images:
21752176
/// - `linear` - simple bilinear demosaicing. Fast, but can produce artefacts along sharp edges.
21762177
/// - `MHC` - Malvar-He-Cutler linear demosaicing algorithm. Slower than `linear`, but produces
21772178
/// significantly better results.
2179+
/// - `auto` - same as "MHC"
21782180
///
21792181
/// The following algorithms are supported for X-Trans-pattern images:
21802182
/// - `linear` - simple linear demosaicing. Fast, but can produce artefacts along sharp edges.
2183+
/// - `auto` - same as "linear"
21812184
///
2182-
/// - "layout" : string (default: "RGGB" for Bayer, "GRBGBR BGGRGG RGGBGG GBRGRB RGGBGG BGGRGG" for X-Trans)
2185+
/// - "layout" : string (default: "auto")
21832186
///
2184-
/// The order the color filter array elements are arranged in, pattern-specific.
2187+
/// The order the color filter array elements are arranged in, pattern-specific. The Bayer pattern sensors
2188+
/// usually have 4 values in the layout string, describing the 2x2 pixels region. The X-Trans pattern
2189+
/// sensors have 36 values in the layout string, describing the 6x6 pixels region (with optional
2190+
/// whitespaces separating the rows). When set to "auto", OIIO will try to fetch the layout from the
2191+
/// "raw:FilterPattern" attribute of the source image buffer, falling back to "RGGB" for Bayer,
2192+
/// "GRBGBR BGGRGG RGGBGG GBRGRB RGGBGG BGGRGG" for X-Trans if absent.
21852193
///
2186-
/// - "white-balance" : float[3] or float[4], (default: {1.0, 1.0, 1.0, 1.0})
2194+
/// - "white_balance_mode" : string (default: "auto")
2195+
///
2196+
/// White-balancing mode. The following modes are supported:
2197+
/// - `auto` - OIIO will try to fetch the white balancing weights from the "raw:WhiteBalance"
2198+
/// attribute of the source image buffer, falling back to {1.0, 1.0, 1.0, 1.0} if absent.
2199+
/// - `manual` - The white balancing weights will be taken from the attribute `white_balance` (see below)
2200+
/// if present, falling back to {1.0, 1.0, 1.0, 1.0} if absent.
2201+
/// - `none` - no white balancing will be performed.
2202+
///
2203+
/// - "white_balance" : float[3] or float[4]
21872204
///
21882205
/// Optional white-balancing weights. Can contain either three (R,G,B), or four (R,G1,B,G2) values.
21892206
/// The order of the white balance multipliers does not depend on the matrix layout.

src/libOpenImageIO/imagebufalgo_demosaic.cpp

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace {
1919
static const ustring pattern_us("pattern");
2020
static const ustring algorithm_us("algorithm");
2121
static const ustring layout_us("layout");
22+
static const ustring white_balance_mode_us("white_balance_mode");
2223
static const ustring white_balance_us("white_balance");
2324

2425
} // namespace
@@ -970,7 +971,8 @@ demosaic(ImageBuf& dst, const ImageBuf& src, KWArgs options, ROI roi,
970971
std::string pattern;
971972
std::string algorithm;
972973
std::string layout;
973-
float white_balance_RGBG[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
974+
std::string white_balance_mode;
975+
float custom_white_balance_RGBG[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
974976
std::string error;
975977

976978
for (auto&& pv : options) {
@@ -992,22 +994,29 @@ demosaic(ImageBuf& dst, const ImageBuf& src, KWArgs options, ROI roi,
992994
} else {
993995
dst.errorfmt("ImageBufAlgo::demosaic() invalid layout");
994996
}
997+
} else if (pv.name() == white_balance_mode_us) {
998+
if (pv.type() == TypeString) {
999+
white_balance_mode = pv.get_string();
1000+
} else {
1001+
dst.errorfmt(
1002+
"ImageBufAlgo::demosaic() invalid white_balance_mode");
1003+
}
9951004
} else if (pv.name() == white_balance_us) {
9961005
if (pv.type() == TypeFloat && pv.nvalues() == 4) {
9971006
// The order in the options is always (R,G1,B,G2)
998-
white_balance_RGBG[0] = pv.get_float_indexed(0);
999-
white_balance_RGBG[1] = pv.get_float_indexed(1);
1000-
white_balance_RGBG[2] = pv.get_float_indexed(2);
1001-
white_balance_RGBG[3] = pv.get_float_indexed(3);
1007+
custom_white_balance_RGBG[0] = pv.get_float_indexed(0);
1008+
custom_white_balance_RGBG[1] = pv.get_float_indexed(1);
1009+
custom_white_balance_RGBG[2] = pv.get_float_indexed(2);
1010+
custom_white_balance_RGBG[3] = pv.get_float_indexed(3);
10021011

1003-
if (white_balance_RGBG[3] == 0)
1004-
white_balance_RGBG[3] = white_balance_RGBG[1];
1012+
if (custom_white_balance_RGBG[3] == 0)
1013+
custom_white_balance_RGBG[3] = custom_white_balance_RGBG[1];
10051014
} else if (pv.type() == TypeFloat && pv.nvalues() == 3) {
10061015
// The order in the options is always (R,G,B)
1007-
white_balance_RGBG[0] = pv.get_float_indexed(0);
1008-
white_balance_RGBG[1] = pv.get_float_indexed(1);
1009-
white_balance_RGBG[2] = pv.get_float_indexed(2);
1010-
white_balance_RGBG[3] = white_balance_RGBG[2];
1016+
custom_white_balance_RGBG[0] = pv.get_float_indexed(0);
1017+
custom_white_balance_RGBG[1] = pv.get_float_indexed(1);
1018+
custom_white_balance_RGBG[2] = pv.get_float_indexed(2);
1019+
custom_white_balance_RGBG[3] = custom_white_balance_RGBG[2];
10111020
} else {
10121021
dst.errorfmt("ImageBufAlgo::demosaic() invalid white balance");
10131022
}
@@ -1033,12 +1042,52 @@ demosaic(ImageBuf& dst, const ImageBuf& src, KWArgs options, ROI roi,
10331042

10341043
IBAprep(dst_roi, &dst, &src, nullptr, &dst_spec);
10351044

1036-
if (pattern.length() == 0)
1037-
pattern = "bayer";
1045+
if (pattern.empty())
1046+
pattern = "auto";
1047+
if (layout.empty())
1048+
layout = "auto";
1049+
if (algorithm.empty())
1050+
algorithm = "auto";
1051+
1052+
if (layout == "auto") {
1053+
layout = src.spec().get_string_attribute("raw:FilterPattern");
1054+
}
1055+
1056+
if (pattern == "auto") {
1057+
size_t l = layout.length();
1058+
if ((l == 6 * 6 + 5) || (l == 6 * 6))
1059+
pattern = "xtrans";
1060+
else
1061+
pattern = "bayer";
1062+
}
1063+
1064+
if (white_balance_mode.length() == 0)
1065+
white_balance_mode = "auto";
1066+
1067+
float white_balance_RGBG[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
1068+
1069+
if (white_balance_mode == "auto") {
1070+
auto pv = src.spec().find_attribute("raw:WhiteBalance");
1071+
if ((pv != nullptr) && (pv->type() == TypeDesc(TypeDesc::FLOAT, 4))) {
1072+
// The order in the options is always (R,G1,B,G2)
1073+
white_balance_RGBG[0] = pv->get_float_indexed(0);
1074+
white_balance_RGBG[1] = pv->get_float_indexed(1);
1075+
white_balance_RGBG[2] = pv->get_float_indexed(2);
1076+
white_balance_RGBG[3] = pv->get_float_indexed(3);
1077+
}
1078+
} else if (white_balance_mode == "manual") {
1079+
white_balance_RGBG[0] = custom_white_balance_RGBG[0];
1080+
white_balance_RGBG[1] = custom_white_balance_RGBG[1];
1081+
white_balance_RGBG[2] = custom_white_balance_RGBG[2];
1082+
white_balance_RGBG[3] = custom_white_balance_RGBG[3];
1083+
} else if (white_balance_mode != "none") {
1084+
dst.errorfmt("ImageBufAlgo::demosaic() unknown white balance mode {}",
1085+
white_balance_mode);
1086+
}
10381087

10391088
if (pattern == "bayer") {
1040-
if (algorithm.length() == 0) {
1041-
algorithm = "linear";
1089+
if (algorithm == "auto") {
1090+
algorithm = "MHC";
10421091
}
10431092

10441093
if (algorithm == "linear") {
@@ -1057,7 +1106,7 @@ demosaic(ImageBuf& dst, const ImageBuf& src, KWArgs options, ROI roi,
10571106
dst.errorfmt("ImageBufAlgo::demosaic() invalid algorithm");
10581107
}
10591108
} else if (pattern == "xtrans") {
1060-
if (algorithm.length() == 0) {
1109+
if (algorithm == "auto") {
10611110
algorithm = "linear";
10621111
}
10631112

0 commit comments

Comments
 (0)