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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 27th August 2020, 00:16   #1  |  Link
VideoOnTapes
Registered User
 
Join Date: Aug 2020
Location: France
Posts: 4
Recolorization of black and white frames

Hi there,

I'm newbie with AviSynth. I use AviSynth+ 64bit and AvsPmod 2.6.3.4.

I'm looking to restore old VHS recordings where some frames are in black and white.
Something similar to what's been done here: https://www.youtube.com/watch?v=iaUsvKDQycg

I figured out how to do it with MergeChroma() :

Code:
frame_number_with_good_colors = 128
good_frame= clip.Trim(frame_number_with_good_colors,1)

# Apply MergeChroma for frames with bad chroma (AverageChromaU() < 120)
# Apply MergeChroma for frames in black and white (vPlaneMedian() = 127 or 128)
copy=clip
chromed=MergeChroma(clip, good_frame)
clip=ConditionalSelect(clip,"v_median=vPlaneMedian()"+chr(13) \
+ "av_chromaU=AverageChromaU()"+chr(13) \
+"(v_median==128 || v_median==127)?1:(av_chromaU<120?1:0)", copy, chromed)
What I'd like to do is use the color values from the last frame that is correct.
To do this, I need to store the number of this correct frame, as it has to be reused until a new frame with correct colors is found.

However, I can't store the current_frame value in a variable. Could you help me on this point?

Also, I tried to write this value to a file:

Code:
clip = clip.WriteFile("variable.txt", "current_frame")
but it doesn't work for me :
Quote:
Script error: Invalid arguments to function 'WriteFile'

NB: The video I'm working on (as a test basis) is this one:
https://www.youtube.com/watch?v=rX0r6WbiutU
VideoOnTapes is offline   Reply With Quote
Old 27th August 2020, 00:46   #2  |  Link
manono
Moderator
 
Join Date: Oct 2001
Location: Hawaii
Posts: 7,356
It looks to me the B+W frames aren't many in number consecutively and the movement is so little between frames, that it would be a whole lot easier to use frame interpolation to create good frames from bad. It would be manual, though, and you seem to be searching for an automatic solution.
manono is offline   Reply With Quote
Old 27th August 2020, 13:28   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,422
Im kinda curious if SpotLess could do anything here [AND ALSO with your problem in other thread],
(It could be that old thing TheFluff keeps on saying, something like, "when all you have is a hammer, every problem looks like a nail", or summick like that).
But might still be worth a try.
Maybe try something like, [both of these, varying RadT downwards, maybe in steps of 5 at first]
Code:
SpotLess(RadT=30, ThSAD2=10000,BlkSz=32)
and
Code:
SpotLess(RadT=30, ThSAD2=400,BlkSz=32)
cant do any harm to try. [do report good or bad, I'm not expecting anything particularly good, but hell, its worth a shot, and it aint the end of the world if it fails].
If it does fix some, then might be required to fix single frames using eg Clipclop or ReplaceFramesSimple. [If ClipClop, then SawBones might be useful]
[will also likely be slow-ish]

EDIT:
Code:
AviSource("D:\Parade.avi")

Global frame_number_with_good_colors = 128
good_frame= Trim(frame_number_with_good_colors,-1)                 # -1, NOT 1

# Apply MergeChroma for frames with bad chroma (AverageChromaU() < 120)
# Apply MergeChroma for frames in black and white (vPlaneMedian() = 127 or 128)

copy=Last
chromed=MergeChroma(clip, good_frame)

# Always way easier than all the Chr(13) stuff, [also, I dont like use of Chr(13), should be Chr(10) IMHO].
SSS = """
    v_median = vPlaneMedian()
    Result   = ((v_median==128 || v_median==127) || AverageChromaU < 120) ? 1 : 0
    Global frame_number_with_good_colors = (Result == 1) ? current_frame : frame_number_with_good_colors    # Will this do ?
#   (Result == 1) ? RT_WriteFile(".\variable.txt","%d",current_frame) : NOP                                 # I always find Writefile type stuff awkward, so dont/rarely use it [Not using Append=true]
    Return Result
"""

ConditionalSelect(Last, SSS , copy, chromed)
Clip = Last # if you need it in clip
Above untested at all.

EDIT: RT_WriteFile from RT_Stats.
If you want write list of frames to ".\variable.txt", Add Append=true, at end of RT_WriteFile( ... , Append=true)
EDIT: I tend to use "SSS" not because it is ending of my moniker, but means triple quoted string, "S" being single quoted string.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 27th August 2020 at 15:03.
StainlessS is offline   Reply With Quote
Old 27th August 2020, 14:35   #4  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 4,324
RE: internal AVS WriteFile()

Something buggy with avs+ versions . It works ok in avs 2.6 classic . Just simple script like colorbars with writefile . I think it has something to do with the "implied last" issues in recent versions. But explicitly assigning names/variables without "last" does not work either
poisondeathray is offline   Reply With Quote
Old 27th August 2020, 14:46   #5  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,422
works a tiny little bit to mod color [not really tweaked at all], but is problably not worth pursuing. [although some frames were fixed at least(well nearly) as well as the youtube fix, but not many]

I hacked SpotLess func adding chroma arg, allowing to switch it off in detector. [worked better than on]
Code:
# Hacked with Chroma arg
Function SpotLess(clip c,int "RadT",int "ThSAD2",int "BlkSz",Bool "chroma") {
    RadT   = Default(RadT,2)                              # Temporal radius
    ThSAD2 = Default(ThSAD2,10000)                        # Setting lower, sets SAD thresold to limit blurring effect of more distant reference frame BAD matching blocks.
    BlkSz  = Default(BlkSz,8)                             #
    chroma = Default(chroma,True)
    Assert(1 <= RadT,"SpotLess: 1 <= RadT")
    sup      = c.MSuper(pel=2,sharp=2,hpad=16,vpad=16)
    MultiVec = sup.MAnalyse(multi=true, delta=RadT,blksize=BlkSz,overlap=BlkSz/2,search=4,chroma=chroma)
    c.MCompensate(sup,MultiVec,tr=RadT,ThSAD2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT)  # Temporal median blur only
    SelectEvery(RadT*2+1,RadT)                                             # Return middle frame
}


AviSource(".\Colour stabilization compare -Earls Court -77-.mp4.AVI")
W=Width/2
A=Crop(0,0,W,0)
B=Crop(W,0,0,0)

RadT=10
ThSAD2=10000
BlkSz1=8
BlkSz2=8

C=A.SpotLess(radt=RadT,thsad2=ThSAD2,blksz=BLKSZ1,chroma=true)
D=A.SpotLess(radt=RadT,thsad2=ThSAD2,blksz=BLKSZ2,chroma=false)
TOP = StackHorizontal(A,B)
Bot = StackHorizontal(C,D)
StackVertical(TOP,BOT)

Return Last
Had to use about blkSz 8, did not know was such a small frame clip. [I tried the Queen clip, 2nd one I think]
Are well, at least it was a riveting experiment :0
Spotless has actually [in spotless thread] fixed full frame dropout, and also a nearly totally desaturated frame with full frame width thickish band of bad noise.

OK, well not quite as well as youtube fix[top right], src[top left], Spotless with chroma detect bot left, without chroma detect, bot right. [YT fix probably had a little hand color correction]
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 27th August 2020 at 15:27.
StainlessS is offline   Reply With Quote
Old 29th August 2020, 15:13   #6  |  Link
VideoOnTapes
Registered User
 
Join Date: Aug 2020
Location: France
Posts: 4
Thank you very much for your help. It's very informative.

With SpotLess, it works perfectly. Unfortunately, it isn't very fast given the many treatments that are applied.
I opted for a RadT value of 5 which gives a good compromise in the case of the video I proposed.


With the other script, the frame value that is applied with Trim() is always the one defined at the beginning, despite the use of "global":

Code:
good_frame = clip.Trim(frame_number_with_good_colors,-1)
I tried a lot of things, without success.

Otherwise, I manage to save the value for each frame in a file :
Code:
RT_WriteFile(filename,"%d %d", current_frame, frame_number_with_good_colors, Append=true)

Like this :
Code:
353 353
354 354
355 355
356 355 <-- new reference for this faulty frame
357 355 <-- new reference for this faulty frame
358 355 <-- new reference for this faulty frame
359 359
360 360
361 361
362 362
But I still haven't found the syntax that would allow to read the file and apply MergeChroma only when the value of the variable is different from current_frame.
If you could help me on this point, I would be grateful. Also, may be it could be enough to only save value when needed.

Afterwards, I'm not sure this is the best approach either, since it requires two passes. One to create the file; a second to read the file and apply the changes.
Or may be, I could write the file with another langage (like Python), using data from ffprobe...
VideoOnTapes is offline   Reply With Quote
Old 14th September 2020, 02:29   #7  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,422
OK, came back to this, downloaded your 2nd clip
Quote:
The video I'm working on (as a test basis) is this one
Simple script
Code:
Avisource(".\Interview Jean Jacques Goldman top 50 - 1986 -.mp4.AVI")
ORG=Last
SpotLess(RadT=5,ThSAD=5000,chroma=false,tm=false)
StackHorizontal(ORG,Last)
Prefetch(4)
Updated for SpotLess v1.04.

Makes a world of differrence [well considering the source quality].
I've only tried on about the first 2000 frames, but fixes most of the horrible double frame orange splashes, and even removes a lot of the chroma bands.
Orange flash frames pair 1560/1561 fails to be fixed, reason: is immediately following a scene change, and shortly after orange flash there is a 2nd orange flash.

Anyway, is nearly there just via above simple script.

Below a few consecutive frames showing original left, with chroma horizontal bands and orange flashes, and on right fixed.









EDIT: Above frame fixes are fairly typical, nothing special.

EDIT: Requires SpotLess v1.04.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 15th September 2020 at 22:28.
StainlessS is offline   Reply With Quote
Old 15th September 2020, 22:27   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,422
Above script updated, req spotLess v1.04, all frames fixed, incl frame 1560/1561.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 15th September 2020, 23:59   #9  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,338
What variables did you feed to SpotlessS? Also, it seems like the main change in v1.04 was to add the tHSAD variable. Is that why v1.04 is needed?
johnmeyer is offline   Reply With Quote
Old 16th September 2020, 00:09   #10  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,830
for fun, I tried it with old video I recorded back in the end of 90s https://www.sendspace.com/file/pu7glm but it's almost didn't fix anything

it's very bad record using old JVC from 80s with almost dead video head
and most importantly, it was done by a kid about 10 years old

and since one head is a bit better than the other one SelectEven() after the source call with SpotLess make it better
__________________
See My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 16th September 2020, 00:53   #11  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,338
Doesn't the OP, as well as real.finder, have to adapt this script to work with interlaced video? The usual advice for a temporal filter is:

Code:
SeparateFields()
even = SelectEven(last).Spotless(...)
odd = SelectOdd(last).Spotless(...)
Interleave(even, odd)
Weave()
johnmeyer is offline   Reply With Quote
Old 16th September 2020, 01:03   #12  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,830
Quote:
Originally Posted by johnmeyer View Post
Doesn't the OP, as well as real.finder, have to adapt this script to work with interlaced video? The usual advice for a temporal filter is:

Code:
SeparateFields()
even = SelectEven(last).Spotless(...)
odd = SelectOdd(last).Spotless(...)
Interleave(even, odd)
Weave()
I don't has the digital interlaced source now (but I still have the tape, but I don't think I will re-cap for this experience)

anyway, since it 50 fps it can reinterlaced, but I think it will not make a better result, but I think the code you post should work
__________________
See My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 16th September 2020, 09:27   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,422
Quote:
tHSAD variable. Is that why v1.04 is needed?
Yes.

Main change to prev image script is
Code:
SpotLess(RadT=5,ThSAD=5000,chroma=false,tm=false)
As we now added ThSAD=5000 (defaults 10,000) and ThSAD2 defaults to ThSAD, so thresholds for ALL frames=5000, and so frame at 1560-1 is
mostly ignored (from a different scene) and so dont mess up the numbers [previously, frame 1560-1 got threshold of 10,000, and so not ignored and messed up numbers].
Likewise frame at 1560-2 ignored etc.
2nd orange frame at 1561, also ignores 1561-2 and 1561-3 etc.
Setting only ThSAD2 worked fine for double frame spots, but I really shoulda implemented ThSAD arg too as more flexible thresholds.
The above mentioned v1.04 requirement was only for the un-shown frames 1560 and 1561, the images that are shown are from somewhere else.

Dont really think good idea to handle interlaced with MC by separatefields, pixels jump in and out of one field to the other.

EDIT: As it happens, below from v1.03 would actually have worked too, I just did not try it.
Code:
SpotLess(RadT=5,ThSAD2=5000,chroma=false,tm=false)    # ThSAD would be as v1.03 default 10000
EDIT:
OOps, talking total bo??ocks, only the chroma=false, tm=false fixes it for either version, ThSAD=5000 made no difference.


EDIT: I'm still tryin' to figure out how this thing works too









EDIT: Actually
Code:
SpotLess(RadT=2,ThSAD=5000,chroma=false,tm=false)
Gets it mostly right, but some weird behaviour @ 4081, RadT=4 seems to work all ok on quick look.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 16th September 2020 at 10:10.
StainlessS is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 23:58.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.