Log in

View Full Version : Science project


oof
28th September 2003, 19:18
In an effort to prevent MY VHS tapes from being lost due to
old age, I have decided to put them on DVD via analog capture.
Most of them have an irritating defect wherein the Luma level
appears to change periodically when captured with any device
that has Automatic Gain Control. I would like to investigate the
possibility of adjusting this problem with a software rather than
hardware solution.
I am using an ATI 8500. Its tendency to refuse to capture at all
has been circumvented by modifying an unnecessary DLL. I am
left with how to fix the contrast changes.

I have a solution which is more than 95 % sucessful on a random
movie.

I occurs to me that other people may wish to play with this and
help improve it, purely as an academic exercise.

Here is what I have so far. Comments/Insults welcome.
I'm afraid notepad was the editor


#Avisynth Script

sp = " "
CR = chr(13)


hi_threshold = 15 # Percent
lo_threshold = -15 #
GAIN = 1.7 # Luma adjustment

global y0 = 0
global y1 = 0
global ry = 0

global c0 = 0
global c1 = 0
global rc = 0

global mv_on = false

avisource( "foo.vdr" ).ConvertToYV12()

ov = last # remember the original

# Use ratios for luma change

ScriptClip( last , " y1 = AverageLuma( ) " + CR + \
" ry = (((y1/ y0 )-1)*100) " + CR + \
" y0 = y1 " + CR + \
" mv_on = ( ry <lo_threshold ) ? true : mv_on " + CR + \
" mv_on = ( ry >hi_threshold) ? false : mv_on " + CR + \
" (mv_on) ? Tweak( last , bright = 0 , cont = GAIN ) : last " )

# See what the chroma does
FrameEvaluate( last , " c1 = abs( AverageChromaU( ) + AverageChromaV( ) ) " + CR + \
" rc = ((c1/c0 )-1) *100 " + CR + \
" c0 = c1 " )

ScriptClip( last , "Subtitle( String(ry ) + sp + String(YDifferenceFromPrevious() ) + sp + String( mv_on ) )" )

stackhorizontal( ov, last )

Joe Fenton
29th September 2003, 05:16
Originally posted by oof
In an effort to prevent MY VHS tapes from being lost due to
old age, I have decided to put them on DVD via analog capture.
Most of them have an irritating defect wherein the Luma level
appears to change periodically when captured with any device
that has Automatic Gain Control. I would like to investigate the
possibility of adjusting this problem with a software rather than
hardware solution.
I am using an ATI 8500. Its tendency to refuse to capture at all
has been circumvented by modifying an unnecessary DLL. I am
left with how to fix the contrast changes.

Uh, this is called "Macrovision." It is a form of copy protection to prevent you from copying the tapes. That is why you had to modify the dll in the first place, to bypass the ATI driver support of Macrovision. What is left is that annoying Macrovision flashing that people always bitch about. Go out and get a video corrector to place between the VCR and the video card. The Sima Color Corrector is a decent one.

I have an old VCR which was made before Macrovision that I still like to use for two reasons: 1) it ignores Macrovision and outputs a clean signal, and 2) it was made to last instead of self-destruct after the warranty is up like all modern VCRs. I have had five modern VCRs in the twenty years I have had this older VCR, and it's still going strong.

sh0dan
29th September 2003, 09:13
I had a simpler case, where I got some shots, where autogain had been used. The image was rather static, so I could apply the following script to stabilize the flickering:

global avgluma = -1

frameevaluate("avgluma = (avgluma == -1) ? YPlaneMedian() : avgluma")
scriptclip("(avgluma == -1) ? coloryuv() : coloryuv(off_y=avgluma-YPlaneMedian())")


I found that median proved to be more reliable than AverageLuma().
If there is scenechanges the script could be adapted to reset avgluma at each detected scenechange.

oof
29th September 2003, 13:39
Well, Joe I guess you just don't appreciate subtlety.

Shodan, I'll try median.
Looks like you fix it with a Luma OFFSET
I looked at histograms and I'm pretty sure that the
Luma was Multiplied by about 0.6 during the insidious
attacks.
How to detect scene changes is the problem isn't it ?
I found that average of difference shows a larger number
than difference of average during scene changes, and the
other way around for MV attacks

Thanks, I will continue experiments.

Joe Fenton
30th September 2003, 04:51
Originally posted by oof
Well, Joe I guess you just don't appreciate subtlety.

:D

So I take it you are trying to make a video stabilizer in software... it's a good project for people who don't wish to spend the money. ;)

That's the nice thing about computer video encoding - if something is amiss, you can do something to make it look better. It might slow things down a bit, but you aren't really too concerned about the speed at encode time.

As to detecting scene changes, some of the talk in the Restore24 thread seems like it would apply here. The idea there was to use edge detection to find blended frames. A blended frame would have lower level on the edges than a progressive frame. They used a gamma enhanced edge detection with luma sum to make it a little more reliable. It seems to me you want to do the reverse: blend two frames and then do the edge detection. If the frames are mostly the same, you'll get a good set of edges. A scene change would give two mostly different frames and the edges will be blunted after blending. You might go read the Restore24 thread in AviSynth Usage for a more detailed explanation of what they are doing than my brief hand-waving summary.

Joe Fenton
30th September 2003, 04:53
:rolleyes: Silly me... the Restore24 thread is right below this one. Here's a link to make it easier.

http://forum.doom9.org/showthread.php?s=&threadid=61792

sh0dan
30th September 2003, 19:20
Use this script to have simple scenechange detection:

global avgluma = -1

org = last

frameevaluate("avgluma = (avgluma == -1) ? YPlaneMedian() : avgluma")
scriptclip("(avgluma == -1) ? coloryuv() : coloryuv(off_y=avgluma-YPlaneMedian())")
frameevaluate("avgluma = (YDifferenceFromPrevious(org) > 15.0) ? -1 : avgluma")

It still not very good, and requires linear access.

oof
30th September 2003, 20:02
Thanks
I'm not sure it's appropriate to adjust on an every frame basis
since it is known that Macrovision is applied and removed evety
few seconds. Obviously a script could be written to force
the Average Luma to be constant for every frame.
I am going to try that just to see.
You may notice I have a flag that turns on and off.

I got temporarily stopped when I simply took my original script
and changed AverageLuma() into YPlaneMedian().
It broke the entire script - all variabes were all zero ?!
I note that YPlaneMedian returns int, not float.
Float(YPlaneMedian()) doesn't work either,

Scriptclip( last , " Subtitle( string(Float(YPlaneMedian() )) " )
works ?

Beats me so far