Adding LensShadingCorrection maps and ToneCurve to controls metadata - #356
Adding LensShadingCorrection maps and ToneCurve to controls metadata#356kunzmi wants to merge 1 commit into
Conversation
|
I think this is a great addition to have! Given that this does introduce new controls to the core libcamera code, would you be able to post your patch onto the libcamera-devel mailing list please? The core libcamera team can then review your proposal and once merged, we can backport it to the Raspberry Pi libcamera source tree. |
|
Sure, patch is sent - waiting for approval as I didn't register to the mailing list... |
|
Hi, thanks very much for doing this. I'd like to see this merged. Obviously it will need to go through the mailing list review process, which always involves a bit to to-ing and fro-ing, but I'll start by adding a few comments here on what I'd like to see. But as I said, thanks very much for doing this, I'll be very happy to submit support to PiDNG for this once the data formats and names in libcamera are settled. |
Sorry - both me and Laurent are the moderators but we've both been on holiday at the same time, I'm back today - so I've just let this through. |
davidplowman
left a comment
There was a problem hiding this comment.
As I said, thanks very much and I would very much like to see this merged to mainline. Am happy to take care of the PiDNG end of things myself once this is in.
| description: | | ||
| A map giving the lens shading correction factors for blue channel. | ||
| size: [n] | ||
|
|
There was a problem hiding this comment.
My personal preference is probably for a single metadata control for this, maybe LensShadingCorrectionTables, or LensShadingTables if the former is too long!
There was a problem hiding this comment.
I agree that one single table would makes things less verbose. Question on this subject: How are monochrome camereas handled (I don't have any to test...)? From what I've seen they just fill RGB with the same values but maintain the RGB channels. Is this correct?
|
|
||
| - LensShadingCorrectionMapBlue: | ||
| type: float | ||
| direction: inout |
There was a problem hiding this comment.
I think everything here needs to be out rather than inout if we haven't implementing setting the control, rather than just finding out what was used.
| direction: inout | ||
| description: | | ||
| The size of the lens shading correction maps in pixels. | ||
| size: [2] |
There was a problem hiding this comment.
With one table this would go up to 3 items. Probably we should store the gains in planar form rather than interleaved, as I think that matches what's in the DNG files. So for Pi 5, I guess this would report [3, 32, 32].
There was a problem hiding this comment.
DNG is actually interleaved, so [32, 32, 3]
| iterator++; | ||
| *iterator = static_cast<float>(y); | ||
| iterator++; | ||
| }); |
There was a problem hiding this comment.
The iterator feels a bit verbose here. Could we leave it out and do
contrast->push_back(x);
contrast->push_back(y);
instead?
| { &controls::rpi::ScalerCrops, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) } | ||
| } }, | ||
| const std::map<const std::string, ControlInfoMap::Map> platformControls{ | ||
| { "pisp", { { &controls::rpi::ScalerCrops, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) } } }, |
There was a problem hiding this comment.
I don't super-love the formatting that it forces on you here. Could we do something like
const ControlInfoMap::Map pispControls = {
{ { &controls::rpi::ScalerCrops, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) } }
};
const std::map<const std::string, ControlInfoMap::Map> platformControls{
{ "pisp", pispControls },
};
It looks slightly less hideous, and would be extensible if we had vc4-only controls.
There was a problem hiding this comment.
clang-format was changing a few more things that I reverted before committing, it seems I missed this one :)
| g[i] = static_cast<float>(alscStatus->g[i]); | ||
| b[i] = static_cast<float>(alscStatus->b[i]); | ||
| } | ||
| uint32_t sizeTable[] = { alscStatus->cols, alscStatus->rows }; |
There was a problem hiding this comment.
Wondering if we could call std::copy three times instead?
There was a problem hiding this comment.
I was also wondering if we should write the table as doubles, too? Is there some specific reason for the higher precision or are floats just fine?
| The size of the lens shading correction maps in pixels. | ||
| size: [2] | ||
|
|
||
| - ToneCurve: |
There was a problem hiding this comment.
ToneCurve? GammaCurve? I expect folks will want to debate the name...
There was a problem hiding this comment.
I'd argue that GammaCurves are a subset of ToneCurves :)
|
Thanks for the comments! I'll wait for comments on the mailing list and will update then... Another question: The colour temperatures for the different CCM calibrations, I suppose these are the estimates from AWB and not some reference lights like D65 or StandardA? Only if the CCMs are calibrated with standard illuminants it would make sense to add ColorMatrix1 and ColorMatrix2 to the DNG so that one could do "correct" white balancing adjustments in photoshop/darktable later on. But if these are just estimates, it is better to maintain the single ColorMatrix as it is right now. |
|
Hi again, just a few little things...
|
|
| The nominal range is [-180, 180], where 0° leaves hues unchanged and the | ||
| range wraps around continuously, with 180° == -180°. | ||
|
|
||
| - LensShadingCorrectionMapRed: |
There was a problem hiding this comment.
Isn't reporting tables per every frame unconditionally quite some data to pass around ? Are you planning for a control to enable/disable tables reporting ?
There was a problem hiding this comment.
This is an option if we want it. All in all, it's around 12kb, so not a huge amount.
There was a problem hiding this comment.
Your suggestion would be something similar to AeEnable at the very top of this file? And report the tables only if set to true - sounds reasonable to me
There was a problem hiding this comment.
See also:
libcamera/src/libcamera/control_ids_rpi.yaml
Lines 10 to 18 in 6c1dd9d
There was a problem hiding this comment.
Maybe not a huge amount (but not super tiny either). It's anyway data that have to be copied for each frame, and I guess it's fair to be able to enable/disable that.
A boolean control (like AeEnable and many other should do). We already have LensShadingCorrectionEnable to enable/disable the algorithms, myabe LensShadingTablesEnable or something similar ?)
For reference, Android has a similar control: https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
There was a problem hiding this comment.
However, maybe it's a discussion to be had on the mailing list ?
We do LSC before demosaic, but so long as everything is linear it doesn't particularly matter. I think a DNG file gets to say what the order of the tables is, so there's no particular problem there. As I said, my impression is that OpcodeList2 is a bit more widely supported, but I'm not an expert on this and could be wrong there.
Works for me! |
…s metadata Having the LensShadingCorrection maps and ToneCurves available in frame metadata allows creating a DNG file with all necessary information so that the DNG matches the JPEG image without colour casts. I opened a PR in raspberrypi/rpicam-apps (raspberrypi/rpicam-apps#928) improving the colour accuracy of said DNG files created by these apps. The information needed is currently not provided by libcamera in the frame metadata. This patch intends to add LensShadingCorrection maps and ToneCurve to the controls metadata in libcamera, so that DNG files can be written with correct colours. Signed-off-by: Michael Kunz <mkunz@articimaging.eu>
eb6e4ed to
e6db90d
Compare
|
Updated the PR according to the comments, the main changes are:
The PR raspberrypi/rpicam-apps#928 is also updated to take the changes into account. I also sent an update to the mailing list, so everything should be in sync :) |
|
@kbingham do you know if this patch is still waiting to be approved on the mailing list? I haven't seen it yet... |
Hrm.. I definitely wrote this after I'd (believed I had) hit the approve button:
And yet - nothing is in my inbox either after the moderation email. I can only fear I might have pushed the wrong button and discarded by mistake ? @kunzmi I'm sorry to ask, but could you resend please ? |
|
Hi, sure I can send the patch again once I'm back to my Pi5 tomorrow. But before I do this and spam you the mailing list, I can see both patches (original and update) in the August archive, so they are there somehow? |
|
@kbingham Hi again, I just sent a v3 to the mailing list with the same changes as the v2. Did you receive anything? |
Thank you for resending, but I'm afraid it's still not getting through. I can see you are listed in the 'automatically accept' list, So I suspect there's something else going on with the list-server. You weren't moderated (you're marked as an approved sender), and it's been received in the archives (https://lists.libcamera.org/pipermail/libcamera-devel/2026-August/061628.html) - but not sent out? I know there were some DKIM/SPF changes lately so I wonder if it's related to that. Do you have a custom email server by any chance ? Are you sending mails which would fail DKIM/SPF challenges ? |
Having the LensShadingCorrection maps and ToneCurves available in frame metadata allows creating a DNG file with all necessary information so that the DNG matches the JPEG image without colour casts.
(This is a necessary change for another PR in rpicam-apps)