Log in

View Full Version : ColourWarp - smooth manual remapping of UV colours for colour correction


wonkey_monkey
27th November 2019, 22:06
https://i.imgur.com/jaDv0fr.png

ColourWarp v0.1 (http://horman.net/avisynth/)

ColourWarp is a filter I've quickly knocked up to remap the colours of YUV video. It's not highly optimised or anything and may have bugs (although I haven't found any yet).

It only works on 8-bit YUV video at the moment, and it only remaps the UV channels. If there's any interest, I might update it to full YUV remapping but I'm not sure how useful that would be.

Colours are remapped by specifying control point pairs of UV values:


ColourWarp(clip, 0,0, -64,-64)
# a single pair will shift the colours

ColourWarp(clip, 0,0, 0,0, 64,64, 32,32)
# two pairs will scale/rotate (this example will reduce saturation of all colours - it fixes grey to grey and then scales 64,64 down to 32,32)

ColourWarp(clip, 0,0, 0,0, 0,128, 0,0, -128,-128, -128,-128, 128,-128, 128,-128, -128,128, -128,128, 128,128, 128,128)
# this example fixes all the corners, and center, of the UV square, but remaps U=0,V=128 to U=0,V=0 (grey)


This image hopefully demonstrates the idea: https://i.imgur.com/q6tI4xq.jpg

You can also specify up to two additional clips (if only one clip is specified, the input clip is assumed to the first "extra" clip). These two clips act as sources for you to pick specific pixels (any number parameters that come after the pixel source clips) to be remapped:


ColourWarp(clip, 0,0, 0,0, clip1, clip2, 0,100,150, 10,200,250)
# this example fixes grey to grey (the first four numbers),
# then maps the colour of pixel [100,150] from clip1, frame 0 to
# the colour of pixel [200,250] from clip2, frame 10)


Noisy clips should be blurred (why not use FastBlur (https://forum.doom9.org/showthread.php?t=176564)?) before using them as sources for pixels in this way. The example at the top of this post was done this way, specifying corresponding pixels from the two clips to remap the first clip to roughly the same colours as the middle clip.

I hate writing documentation and to be honest I'm already pretty bored of writing this post, but I'm better at answering questions, so ask away.

real.finder
27th November 2019, 22:41
(why not use FastBlur (https://forum.doom9.org/showthread.php?t=176564)?)

cuz no source code available yet :devil:

wonkey_monkey
27th November 2019, 23:05
Yeah, well, that's only because I'm lazy and made it a dependency nightmare. You can still use any boring slow blurrer for this use case ;)

StainlessS
27th November 2019, 23:26
No excuses, get the source up, you know how short temptered Real.Finder is.

EDIT: Please.

lansing
28th November 2019, 02:53
How do I do a simple clip1 remap to clip2? The 2 clips are the same size.

wonkey_monkey
28th November 2019, 13:15
You need to specify a set of pixels to be mapped between - it isn't automatic. If the two clips are already aligned, you could pick points at random, but you're probably better off picking a few with high saturation, widely spaced around the UV square, plus one grey point.

clip1.ColourWarp(clip2,\
f11,x11,y11, f21,x21,y21,\
f12,x12,y12, f22,x22,y22,\
f13,x13,y13, f23,x23,y23\
)

That will map the colour of pixel [x11,y11] from clip 1, frame f11, to the colour of pixel [x21,y21] from clip2, frame f21, and so on.

I suppose I could add a mode which automatically finds the most saturated pixels (again, assuming the clips are already aligned, which isn't the case for the clips I wrote this for).

lansing
28th November 2019, 17:56
You need to specify a set of pixels to be mapped between - it isn't automatic. If the two clips are already aligned, you could pick points at random, but you're probably better off picking a few with high saturation, widely space around the UV square, plus one grey point.

clip1.ColourWarp(clip2,\
f11,x11,y11, f21,x21,y21,\
f12,x12,y12, f22,x22,y22,\
f13,x13,y13, f23,x23,y23\
)

That will map the colour of pixel [x11,y11] from clip 1, frame f11, to the colour of pixel [x21,y21] from clip2, frame f21, and so on.

I suppose I could add a mode which automatically finds the most saturated pixels (again, assuming the clips are already aligned, which isn't the case for the clips I wrote this for).

Yeah it should have some mode that does the mapping automatically. Nobody is going to map one pixel per frame at a time for all frames

poisondeathray
28th November 2019, 18:20
Yeah it should have some mode that does the mapping automatically. Nobody is going to map one pixel per frame at a time for all frames

For that, why wouldn't you use something like mergechroma instead ?

http://avisynth.nl/index.php/Merge#MergeChroma

lansing
28th November 2019, 18:34
For that, why wouldn't you use something like mergechroma instead ?

http://avisynth.nl/index.php/Merge#MergeChroma

Because I want to see how it does on color matching, since he mentioned about it with the Star War sample.

wonkey_monkey
28th November 2019, 21:11
Yeah it should have some mode that does the mapping automatically. Nobody is going to map one pixel per frame at a time for all frames

I am, because it's the only way to get decent results from some videos.

You don't need to do it for every frame. You can select pixels from just a single pair of frames, if they've got enough colours to give you a decent map. Or no frames at all, by giving it direct UV values as inputs.

As for using mergechroma, this isn't always the best solution even if you can align your clips. Your target might be lower resolution, or noisy, or just not have the same vibrancy and range of colours to begin with.

zorr
28th November 2019, 21:36
I've had good results with MatchHistogram (https://forum.doom9.org/showthread.php?p=1729864#post1729864), or rather the VapourSynth port of it. It does require that the frames are aligned so it may not work in your case. In the VS version (https://github.com/dubhater/vapoursynth-matchhistogram) you can calculate the histogram from two clips and apply the histogram to a third clip, this way you can match the colors of specific part of the frames and apply them to the whole frame, for example.

lansing
28th November 2019, 23:08
I am, because it's the only way to get decent results from some videos.

You don't need to do it for every frame. You can select pixels from just a single pair of frames, if they've got enough colours to give you a decent map. Or no frames at all, by giving it direct UV values as inputs.


Well we'll see how the result goes when the automatic mode came out.

spoRv
20th January 2020, 09:40
The color matching in the first post is very nice!

Can you post the code used? Thanks!