I've got an external HDMI screenshotting box which works fine... except when the source is playing UHD HDR, in which case everything becomes very washed out.
For instance:
Now, that's to be expected, because the capture box doesn't do HDR, so it just... er... downsamples to SDR? Or something?
If I just do a contrast stretch with ImageMagick, I get something that looks pretty reasonable.
convert -contrast-stretch 0.20x0.10% IMG_53.JPG norm.jpg
But that's probably not the correct transform? There's some kind of curve between HDR10 and... sRGB?
I've tried googling for the right way to convert here (to get as accurate an image as possible, even if the HDR10 bits have been discarded), but I've been unable to find any solutions. Does anybody know what parameters would yield a good result?
Converting an HDR10 image
-
- Posts: 4
- Joined: 2019-02-15T06:27:13-07:00
- Authentication code: 1152
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting an HDR10 image
According to https://en.wikipedia.org/wiki/High-dyna ... ideo#HDR10 , HDR10 uses the REC2020 colorspace, and the SMPTE ST 2084 (PQ) transfer function. That page also gives the transformation from linear to SMPTE ST 2084.
I notice that the pixel values of your input img_53.jpg range from 0 to 62%. So this might need stretching, ideally in linear colorspace.
So, to convert from HDR10 to sRGB (or whatever you want), the following steps should work:
1. Linearize the HDR10 image (using the inverse of the PQ OETF).
2. Convert from linear Rec2020 to linear sRGB.
3. Stretch the values.
4. Convert from linear sRGB to non-linear sRGB.
For steps 2 and 4, we can use IM's "-profile" operation. They could be combined into a single step if there was no stretching.
However, I don't think your img_53.jpg is encoded as HDR10.
I notice that the pixel values of your input img_53.jpg range from 0 to 62%. So this might need stretching, ideally in linear colorspace.
So, to convert from HDR10 to sRGB (or whatever you want), the following steps should work:
1. Linearize the HDR10 image (using the inverse of the PQ OETF).
2. Convert from linear Rec2020 to linear sRGB.
3. Stretch the values.
4. Convert from linear sRGB to non-linear sRGB.
For steps 2 and 4, we can use IM's "-profile" operation. They could be combined into a single step if there was no stretching.
However, I don't think your img_53.jpg is encoded as HDR10.
snibgo's IM pages: im.snibgo.com
-
- Posts: 4
- Joined: 2019-02-15T06:27:13-07:00
- Authentication code: 1152
Re: Converting an HDR10 image
Yeah, the img_53.jpg is not an HDR10 image -- the HDMI capture box has created a normal 8-bit sRGB image based on the HDR10 that was output by the source.
So it's not really a question of how to convert an HDR10 image per se -- but how to convert these SDR images back to something that looks reasonable... Surely somebody must have had this problem before me.
So it's not really a question of how to convert an HDR10 image per se -- but how to convert these SDR images back to something that looks reasonable... Surely somebody must have had this problem before me.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting an HDR10 image
Okay, so if we assume img_53.jpg is sRGB and the task is to make it "look reasonable", then the image (without the black bands) is an ordinary photo so I would define "reasonable" as pixel values spanning the range 0 to 100% ("-auto-level") with a mean around 0.5 ("-auto-gamma") and a standard deviation around 0.2. By trial and error, "-sigmoidal-contrast 8x50%" gives that SD. So:
If you are processing frames from a video, you don't want -auto-anything because that will create flicker. Instead use "-level X,Y% -evaluate Power P -sigmoidal-contrast Sx50%" where X,Y,P and S are calculated.
Code: Select all
magick img_53.jpg -gravity Center -crop 100x74%+0+0 +repage -auto-level -auto-gamma -sigmoidal-contrast 8x50% -verbose +write info: out.png
snibgo's IM pages: im.snibgo.com
-
- Posts: 4
- Joined: 2019-02-15T06:27:13-07:00
- Authentication code: 1152
Re: Converting an HDR10 image
Thanks! That looks pretty good.
But since the image originated from something that's been through SMPTE ST 2084, and which has then been truncated down do 8-bit sRGB (which is what I assume that the capture box has done), is there a way to do an... inverse 2084? I mean, bits have been lost, so you can't get back to the original 10-bit image, but I would assume that there would be a transform back that doesn't rely on choosing sigmoidal parameters and then eyeballing the results.
Or... perhaps not?
But since the image originated from something that's been through SMPTE ST 2084, and which has then been truncated down do 8-bit sRGB (which is what I assume that the capture box has done), is there a way to do an... inverse 2084? I mean, bits have been lost, so you can't get back to the original 10-bit image, but I would assume that there would be a transform back that doesn't rely on choosing sigmoidal parameters and then eyeballing the results.
Or... perhaps not?
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting an HDR10 image
Yes, and apparently your img_53.jpg has already had that inverse applied.larsmagne23 wrote:... is there a way to do an... inverse 2084?
Based on the Wikipedia page I cited, the forwards 2084 transformation is (Windows BAT syntax):
Code: Select all
set c1=0.8359375
set c2=18.8515625
set c3=18.6875
set m1=0.1593017578125
set m2=78.84375
rem Forwards SMPTE ST 2084 transformation, from linear luminance to signal:
%IMG7%magick ^
-size 1000x1 gradient:black-white ^
-fx "LOM=pow(u,%m1%);PP=(%c1%+%c2%*LOM)/(1+%c3%*LOM);pow(PP,%m2%)" ^
st2084_fwd.png
Code: Select all
rem Reverse SMPTE ST 2084 transformation:
%IMG7%magick ^
-size 1000x1 gradient:black-white ^
-fx "LL=pow(u,1/%m2%);PP=(%c1%-LL)/(%c3%*LL-%c2%);pow(PP,1/%m1%)" ^
st2084_rev.png
If you can link to an original HDR10 image, we can try this out.
Raw images from cameras are usually "flat", ie reasonably accurate colorimetrically, but low in contrast and saturation and sharpness. These operations make the image more understandable and attractive to human viewers.
As your img_53.jpg has a subtitle, I guess it is from an edited movie, not a camera-raw image.
Incidentally, JPG has lossy compression so should never be used as intermediate format in a chain of image processing.
EDIT to add that img_53.jpg, as displayed on a sRGB screen, might look exactly as the author intended. In a movie, one scene may be dimmer or less colorfull or lower contrast than another to create a certain mood. So a single isolated frame may seem "strange", and non-conforming to usual aesthetics of single images.
snibgo's IM pages: im.snibgo.com
-
- Posts: 4
- Joined: 2019-02-15T06:27:13-07:00
- Authentication code: 1152
Re: Converting an HDR10 image
The sigmoidal transform you suggested makes the image look pretty much like what my HDR TV shows, so the washed-out look isn't an artistic choice, I'm afraid.
I don't have the original HDR data available in my setup, which is the major problem I'm having. If I had access to the HDR stream, there are pre-rolled solutions for how to get to a reasonable SDR image: See, for instance, https://stevens.li/guides/video/convert ... th-ffmpeg/
What I have is the output from the HDMI non-HDR screenshotting box, which probably does a similar non-transform as what the guy in the link above does with his "reference" washed-out images...
He's using the zimg ffmpeg filter to get to SDR, and as somebody here mentions: https://github.com/sekrit-twc/zimg/issues/61 Getting a pleasing SDR image from an HDR image may sometimes involve handholding, since we're truncating a larger colourspace into sRGB...
So, in my case, where we've first discarded lots of bits, and then want to do, er, something to that resulting JPEG to make it look closer to what it should have been, perhaps contrast stretching and sigmoidal transforms are as good as we're going to get...
But it would feel more satisfying with a more math-ey solution.
I don't have the original HDR data available in my setup, which is the major problem I'm having. If I had access to the HDR stream, there are pre-rolled solutions for how to get to a reasonable SDR image: See, for instance, https://stevens.li/guides/video/convert ... th-ffmpeg/
What I have is the output from the HDMI non-HDR screenshotting box, which probably does a similar non-transform as what the guy in the link above does with his "reference" washed-out images...
He's using the zimg ffmpeg filter to get to SDR, and as somebody here mentions: https://github.com/sekrit-twc/zimg/issues/61 Getting a pleasing SDR image from an HDR image may sometimes involve handholding, since we're truncating a larger colourspace into sRGB...
So, in my case, where we've first discarded lots of bits, and then want to do, er, something to that resulting JPEG to make it look closer to what it should have been, perhaps contrast stretching and sigmoidal transforms are as good as we're going to get...
But it would feel more satisfying with a more math-ey solution.