How to white balance a photo in vkdt?

If I open a photo shot under 2700K lighting (with the camera white balance set to 2700K) in vkdt using the default pipeline, it shows a very orange tint. It clearly isn’t acting upon the white balance information from EXIF.
What do I need to do to get it to do that?

Hannos already answer this question when I asked for an automated feature.

Thanks. pick-neutral works in this case

Colin,

What camera are you using? I’m not familiar with any camera that actually specifies a temperature in their WB metadata; all I’ve seen specify it as the RGB multipliers.

Once you walk away from the scene and its illumination sources, color temperature doesn’t mean a lot. Most softwares provide an approximation in their tools that let you specify such, but it has to be transformed to RGB multipliers to actually be applied to the image. And, that transform is a bit dodgy…

Nikon Z9.
I haven’t looked at how it specifies the WB information in EXIF, but it will be there in some form.

colour-monk-1 also works very well.
There is a difference it seems in how they work though. With the colour-monk presets, the white red, white green and white blue values in colour 01 are altered. With pick-neutral they are not (they remain all at 0.5).

the monk colour scale is for skin tones. so the patch you pick will be moved to be this particular skin tone (i think 0 is very pale). you can achieve the same by dialing in the wb multipliers (the target colour of the patch), but i thought as preset sometimes these skin tone values are actually convenient (if they match the subject, and of course you’ll need to adjust the pick box then).

I downloaded a Z 9 NEF from DPReview, here are the relevant metadata tags:

[MakerNotes] WhiteBalance: Preset1
[MakerNotes] WhiteBalanceFineTune: 0 0
[MakerNotes] WB_RBLevels: 2.162109375 1.18359375 1 1

The WB_RBLevels tag is what libraw uses to convey a white balance to whatever software is using it. Nikon is turning your 2700 into a set of multipliers particular to the camera. Really, the best way to get white balance from the scene is to use the preset mode that lets you take a measurement from a white reference; specifying a color temperature has to run through dodgy conversion algorithms.

FWIW…

Exiftool shows:
WB RB Levels : 1.08984375 2.60546875 1 1

1 Like

if you created a dcp/dual wb lut for the colour module, vkdt will use an interpolation formula to mix the two colour luts (usually one will be illuminant A and the other D65). that means you can interpolate from 2856 to 6504K and get something that at least does not multiply simplistic coefficients to camera rgb values (or matrices, for that matter).

other than that vkdt will use CAT16 to do any extra white balancing (with rgb values for the target directly, no temperature/tint).

i think for most modern cameras the D65 matrix shipped with rawspeed actually contains the rough white balancing step, so i’m not explicitly multiplying these pre-mul wb coefs (i just apply the matrix in case there is no clut requested in the colour module).

I’m trying to figure out how it might be possible to copy the white balance setting from one photo to another. The use case would be for a set of photos taken at the same time under similar lighting conditions, where not all of the photos have a good neutral patch to apply the picker to. The neutral pixel value would be picked from one photo and applied to the other photos in the set.

One possibility would be to modify the colour module so that it can accept the neutral pixel value as a parameter instead of as an input from the picker module.

Another possibility would be to create a new module which has an output exactly like the picker module, but its output value is taken directly from its parameters rather than being calculated from the image. There could be a function that takes an existing picker and creates a preset which hardcodes the current value from that picker in its parameters, then that preset could be applied to the other images.

I think this should be pretty easy to implement, I might give it a try.

ah, good use case, and also good proposals for solutions here.

i think i like your idea of a fake-colour-picker module… i can imagine likely future use cases of such a module. it’s also very similar to a constant colour fill module which might be useful in combination with say a vignetting module + blend modes.

a simple implementation might not even need cpu code (main.c) at all see rendering stuff like the spheres module. in this case the output will default to i think 1024^2 resolution though, which could be changed in the modify_roi_{in,out} callbacks, see how the quake module does it.

as a convenience function to insert the new constant module instead of a pick module, maybe the pick module could implement a ui_callback kind of button (as colour does it) to generate a simple entry point? it could use the history aware graph manipulation stuff in pipe/graph-history.h to modify the graph. i think it might need a convenience function dt_graph_module_add_with_history like in api.hh:360, but that’s details.

anyways let me know if you really start working on this, happy to help out.

I had done the opposite - made a cpu-only module with a source connector that implemented read_source. Would it be preferable to make a shader instead? Is there any reason to exactly reproduce the 24-value output of the existing pick module or should it just have a single value?

So the pick module in the source image would replace itself with an instance of the constant module, and then that line could be copied out of the cfg to other images? Or would it be better to leave the source image graph with the pick module unmodified and just add the new constant module to the destination images?

hm good questions.

#1, cpu or gpu code path:
so, there’s no such thing as a cpu module in vkdt. everything is run on the gpu. the difference here is more subtle:

case 1):
parameters are uploaded transparently as uniforms, and the shader copies them into a buffer in the same layout as the pick module would. this means the uniforms will be uploaded every frame (no big deal, this is not a lot of data). this is slightly less complicated in the overall setup.

case 2):
the read_source callback is used to copy the data from the cpu to a staging buffer, which is later on copied/transferred to the final image layout. this staging buffer is cached, so it will only be uploaded once, unless the module explicitly re-requests a source update (or the graph topology changes). it seems for animations this might be (unmeasurably) faster, but more code (grab the parameters from the module manually and copy to the buffer).

no strong opinion here. in both cases i’d probably like it to work in a way that the const module gui allows to manually create an input with a constant colour, for further processing. this gui would not be used in the replace-colour-picker usecase, since the parameters would be filled programmatically to match the picker.

#2, 24 values
i’d probably implement the full thing, just in case. i mean otherwise it won’t be a true drop-in replacement, and the button to replace the pick module will be on the pick module, so you might kinda expect it works in all cases. might need a parameter for image resolution anyways.

#3, replacing modules
i think i’d add a const module (or i-const if it is a source module) with the same instance name and wire the connection instead of the pick module, but leave the pick module in the graph. this way it can be copied transparently (using the existing copy/paste code path), and it will be quick to re-attach the original pick module, even in the other images where the graph cfg was pasted to.

… i pushed a small patch that creates a “freeze” button in the colour picker to wire a constant input instead. let me know if that works!

Hello ! I just try it.

On a first image:

  • When i click on the freeze button :

    • the output of the module pick is disconnected from the input picked of the module colour.
    • a new module called const is created and the its output of this module is connected to the input picked of the module color
  • When i manage the module const i can see the number of nspots and the parameters of each spot, but i can find the position of the nspots. I can or delete or not the module pick. I can modifiy the parameters of the nspots but i can’t add a new nspot (may be useful if i have deleted the module pick…).
    There are two mode for the module const: a mode replace colour picker and a mode constant. Why ?

On a second image, i want to apply the module const created with the first picture, so i try to use the module const of the first image. I don’t find how to do that.

thanks for trying!

so far so good. maybe i should also detach the pick module completely from the graph, it might incur a performance penalty that we don’t want. as a potential sink-to-cpu module it may not be removed by dead code elimination.

yeah maybe i should hide the nspots param from the gui. it doesn’t pick, it has no areas. it just holds numbers.

i think the way to do this would be to reconnect the pick:01 module which will overwrite the values in const:01 again by pressing the freeze button.

oh, you can also wire the const module for instance instead of a draw module to create uniform masks without drawing them. in that case it should prepare a full image-sized buffer filled with constant colour.

this will be copied over if you copy/paste the history stack (ctrl-c/ctrl-v in lighttable) or include it in a preset (ctrl-o in darkroom mode and then include everything const and ctrl-p to apply otherwise)

to create a temporary preset, you could press ctrl-o in darkroom mode, use the box to filter the list (and only display stuff that has const in it), then select the entries, press ok and call the preset tmp or something. you can always delete the file from your local ~/.config/vkdt/presets/ directory later, or just keep overwriting the same preset name by future ctrl-o operations.

i think the way to do this would be to reconnect the pick:01 module which will overwrite the values in const:01 again by pressing the freeze button.

That’s ok. So it should be impossible to delete the pick module.

to create a temporary preset, you could press ctrl-o in darkroom mode, use the box to filter the list (and only display stuff that has const in it), then select the entries, press ok and call the preset tmp or something. you can always delete the file from your local ~/.config/vkdt/presets/ directory later, or just keep overwriting the same preset name by future ctrl-o operations.

I try it and it works fine. I think it’s the good way for that, even if it’s not very easy.

oh, you can also wire the const module for instance instead of a draw module to create uniform masks without drawing them. in that case it should prepare a full image-sized buffer filled with constant colour.

Ok, the const module can be use to create an uniform color over the entire picture aera.

ah, the two modules conspire via their instance id. so you can delete the pick module just fine. if you want to change say const:02 you just need to create a pick:02 module, the freeze button will find the counterpart again.

Ok but by this way, the previous nspots and therefore the settings are lost.