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. |
|
|
#1 | Link |
|
Registered User
Join Date: Feb 2021
Posts: 137
|
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. |
|
|
|
|
|
#2 | Link |
|
Registered User
Join Date: Nov 2009
Posts: 2,375
|
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 |
|
|
|
|
|
#3 | Link | |
|
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,676
|
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. |
|
|
|
|
|
|
#4 | Link |
|
Registered User
Join Date: Nov 2009
Posts: 2,375
|
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 |
|
|
|
|
|
#5 | Link |
|
Registered User
Join Date: Feb 2021
Posts: 137
|
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. |
|
|
|
|
|
#6 | Link | |
|
Registered User
Join Date: May 2018
Posts: 237
|
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 |
|
|
|
|
|
|
#7 | Link |
|
Registered User
Join Date: Nov 2009
Posts: 2,375
|
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. |
|
|
|
|
|
#8 | Link |
|
Registered User
Join Date: Feb 2021
Posts: 137
|
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. |
|
|
|
|
|
#9 | Link | ||
|
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,676
|
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 |
||
|
|
|
|
|
#10 | Link |
|
Registered User
Join Date: Feb 2021
Posts: 137
|
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. |
|
|
|
|
|
#11 | Link |
|
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,676
|
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" |
|
|
|
|
|
#12 | Link |
|
Registered User
Join Date: Feb 2021
Posts: 137
|
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. |
|
|
|
|
|
#13 | Link | |
|
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,676
|
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. |
|
|
|
|
|
|
#15 | Link | |
|
Registered User
Join Date: Sep 2007
Posts: 5,669
|
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. |
|
|
|
|
|
|
#16 | Link | ||
|
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,676
|
Quote:
![]() Quote:
https://github.com/nikolajbech/under...ction/issues/1 |
||
|
|
|
|
|
#17 | Link | |
|
Registered User
Join Date: Dec 2005
Location: Sweden
Posts: 722
|
Quote:
![]() But seriously I am curious to see how this handles skintones, that is what color analog film was all about. |
|
|
|
|
|
|
#18 | Link |
|
Registered User
Join Date: Dec 2005
Location: Germany
Posts: 1,828
|
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth VapourSynth Portable FATPACK || VapourSynth Database |
|
|
|
![]() |
| Tags |
| ffmpeg, filter, grayworld |
| Thread Tools | |
| Display Modes | |
|
|