Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
24th January 2022, 16:31 | #1 | Link |
Registered User
Join Date: Feb 2021
Posts: 131
|
New grayworld video filter in FFmpeg 5.0
The new version of FFmpeg (News) has a grayworld video filter for changing the white balance using an algorithm based on the gray world hypothesis. Read more about the algorithm here.
Help from FFmpeg is here. Code:
11.102 grayworld A color constancy filter that applies color correction based on the grayworld assumption The algorithm uses linear light, so input data should be linearized beforehand (and possibly correctly tagged). ffmpeg -i INPUT -vf zscale=transfer=linear,grayworld,zscale=transfer=bt709,format=yuv420p OUTPUT Is it possible to make a filter or script function for AviSynth? This is a port of the FFmpeg filter grayworld: grayworld Picture from pdf file: The vf_grayworld.c file from the source code in the attachment. (change .txt to .c) Last edited by Arx1meD; 25th April 2022 at 18:42. |
24th January 2022, 18:21 | #2 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,371
|
This is a cheap approach in YUV.
Code:
function GreyWorld(clip a) { rgb = isRGB(a) isy = isy(a) px = PixelType(a) bi = BitsPerComponent(a) fs = propNumElements (a,"_ColorRange") > 0 ? \ propGetInt (a,"_ColorRange") == 0 : rgb ScriptClip(a,function[bi,fs,px] () { U = PlaneMinMaxStats(0, 0, 1, false) V = PlaneMinMaxStats(0, 0, 2, false) H = ex_bs(128, 8, bi, true, float=true) U = H - U[4] V = H - V[4] Expr(last,SwapUV(),"",Format("x {U} +"),Format("x {V} +"), Format=px) } ) }
__________________
i7-4790K@Stock::GTX 1070] AviSynth+ filters and mods on GitHub + Discussion thread |
24th January 2022, 18:54 | #3 | Link | |
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,672
|
Quote:
FFmpeg over the past few years has added a lot of interesting audio/video filters. Most of the unique filters for avs/vs have been ported over to FFmpeg. I'd be nice to access to the collection of filters in AviSynth. GreyWorld() Last edited by Reel.Deel; 24th January 2022 at 19:11. |
|
24th January 2022, 20:38 | #4 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,371
|
Yes, that example wasn't so good, the other one was better but I wanted to avoid going through RGB or LAB since that's very slow. Anyway I had the project in my todo list. There was an attempt before.
__________________
i7-4790K@Stock::GTX 1070] AviSynth+ filters and mods on GitHub + Discussion thread |
24th January 2022, 21:04 | #5 | Link |
Registered User
Join Date: Feb 2021
Posts: 131
|
Dogway,
I know about GrayWorldSimple and ShadesOfGraySimple. They change the white balance quite normally, but they have a big drawback. When the scene changes or when an object with a different color suddenly appears in the frame, the colors flash. Last edited by Arx1meD; 24th January 2022 at 21:08. |
24th January 2022, 21:29 | #6 | Link | |
Registered User
Join Date: May 2018
Posts: 214
|
Quote:
I'd recommend whoever will make an avisynth plugin out of this to take some things from this http://avisynth.nl/index.php/AutoAdjust |
|
24th January 2022, 21:47 | #7 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,371
|
That will happen with mine or the paper algorithm as well because metrics is a different topic. As I said in another thread we need a plugin or something internal that accumulates/averages metrics per scenes. It requires forward look ahead.
EDIT: Improved Code:
function GreyWorld(clip a) { rgb = isRGB(a) isy = isy(a) px = PixelType(a) bi = BitsPerComponent(a) ScriptClip(a,function[bi,px] () { U = PlaneMinMaxStats(1, 0, 1, false) V = PlaneMinMaxStats(1, 0, 2, false) H = ex_bs(128, 8, bi, true, float=true) Ux = H - U[4] Vy = H - V[4] Us = abs(Ux) > abs(Vy) ? "range_half - "+string(U[4] / V[4])+" * range_half +" : "" Vs = abs(Ux) < abs(Vy) ? "range_half - "+string(V[4] / U[4])+" * range_half +" : "" Expr(last,SwapUV(),"",Format("x {Ux} + "+Us),Format("x {Vy} + "+Vs), Format=px) } ) }
__________________
i7-4790K@Stock::GTX 1070] AviSynth+ filters and mods on GitHub + Discussion thread Last edited by Dogway; 24th January 2022 at 22:40. |
31st March 2022, 08:18 | #8 | Link |
Registered User
Join Date: Feb 2021
Posts: 131
|
This is a port of the FFmpeg filter grayworld: grayworld. Thank you very much Asd-g.
The description says the input clip must be in RGB(A) 32-bit planar format and in linear light. I can't understand how to convert the clip to RGB planar format. ConvertToRGB32() and ConvertToPlanarRGBA() filters are not suitable. |
31st March 2022, 08:28 | #9 | Link | ||
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,672
|
Quote:
Code:
z_ConvertFormat(pixel_type="RGBPS", colorspace_op="rgb:srgb:709:full=>rgb:linear:709:full") grayworld() z_ConvertFormat(pixel_type="RGBP16", colorspace_op="rgb:linear:709:full=>rgb:srgb:709:full") Edit: tested it with the example image in the first post: Code:
# load jpeg in native YUV colorspace, convert it to linear RGB, process it with # grayworld() and finally convert the result back to 8-bit sRGB. FFImageSource("KdoTPHuv_o.jpg") z_ConvertFormat(pixel_type="RGBPS", colorspace_op="601:601:470bg:full=>rgb:linear:470bg:full", chromaloc_op="center=>center") grayworld() z_ConvertFormat(pixel_type="RGBP8", colorspace_op="rgb:linear:709:full=>rgb:srgb:709:full") Hmm, result looks a little different than in the example. I found the original image here: https://i2.wp.com/worldadventuredive...8/img_4477.jpg Quote:
Last edited by Reel.Deel; 31st March 2022 at 11:54. Reason: typo |
||
31st March 2022, 11:27 | #10 | Link |
Registered User
Join Date: Feb 2021
Posts: 131
|
Thank you Reel.Deel
I made several tests comparing the result of different filters. Source clips: source_bubbles, source_carnival, source_cat My comparison result of grayworld, GamMac and AWB filters: Video comparison: test_bubbles, test_carnival, test_cat It is difficult to compare which filter is better. I think, when the colors are heavily distorted, then grayworld gives better results, and when the colors are almost normal, then the result is worse. Last edited by Arx1meD; 31st March 2022 at 11:29. |
31st March 2022, 14:20 | #11 | Link |
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,672
|
I can't get the same results as the example picture. In the example result it looks better, the highlights are not blown out. I tried FFmpeg also and get similar results to AviSynth.
Not very experienced with FFmpeg but I used this: Code:
ffmpeg -i "img_4477.jpg" -vf zscale=transfer=linear,format=gbrpf32be,grayworld,zscale=transfer=bt709,format=rgba "img_4477.png" |
31st March 2022, 16:55 | #12 | Link |
Registered User
Join Date: Feb 2021
Posts: 131
|
Reel.Deel, I took picture examples from Bianco_etal_ISPRS_CIPA.pdf
It seems to me that vf_grayworld.c has a different algorithm than Bianco_etal_ISPRS_CIPA.pdf (see APPENDIX on the last page). From vf_grayworld.c: Code:
static const float lms2lab[3][3] = { {0.5774, 0.5774, 0.5774}, {0.40825, 0.40825, -0.816458}, {0.707, -0.707, 0} }; static const float lab2lms[3][3] = { {0.57735, 0.40825, 0.707}, {0.57735, 0.40825, -0.707}, {0.57735, -0.8165, 0} }; static const float rgb2lms[3][3] = { {0.3811, 0.5783, 0.0402}, {0.1967, 0.7244, 0.0782}, {0.0241, 0.1288, 0.8444} }; static const float lms2rgb[3][3] = { {4.4679, -3.5873, 0.1193}, {-1.2186, 2.3809, -0.1624}, {0.0497, -0.2439, 1.2045} }; Last edited by Arx1meD; 31st March 2022 at 17:13. |
31st March 2022, 20:43 | #13 | Link | |
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,672
|
Interesting find Arx1meD. Looking around I found another implementation in Python:
Edit: I found this page: Paralenz color correction algorithm and it produces a decent looking result for the example image. The GitHub page describes the process: Quote:
Last edited by Reel.Deel; 1st April 2022 at 09:04. |
|
1st April 2022, 15:11 | #15 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,599
|
Quote:
I ran the python script and was not able to reproduce the paper results using "KdoTPHuv_o.jpg" as input "--lab_constrast_correction equalisation" mode came the closest but there was still channel clipping, and playing with --constrast_cut_off values did not help Code:
parser.add_argument('--colour_correction', default="LAB", help="perform colour correction in [LAB, CIELAB, LUV, YCBC] spaces") parser.add_argument('--lab_constrast_correction', default="none", help="perform contrast correction with [stretching, CLAHE, equalisation, none] methods") parser.add_argument('--constrast_cut_off', default=1e-3, help="cut-off level for lab contrast correction") paralenz - Yes, and red channel looks damaged or missing (pinkish splotch below fish becomes blue) . Maybe some of the settings can be altered to reduce the channel loss ? Last edited by poisondeathray; 1st April 2022 at 15:15. |
|
1st April 2022, 15:31 | #16 | Link | ||
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,672
|
Quote:
Quote:
https://github.com/nikolajbech/under...ction/issues/1 |
||
1st April 2022, 15:38 | #17 | Link | |
Registered User
Join Date: Dec 2005
Location: Sweden
Posts: 721
|
Quote:
But seriously I am curious to see how this handles skintones, that is what color analog film was all about. |
|
1st April 2022, 15:43 | #18 | Link |
Registered User
Join Date: Dec 2005
Location: Germany
Posts: 1,822
|
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth VapourSynth Portable FATPACK || VapourSynth Database |
Tags |
ffmpeg, filter, grayworld |
Thread Tools | Search this Thread |
Display Modes | |
|
|