Sorry, I forgot that I had included coring=false: levels(0,1,255,16,235,coring=false):
SourceRGB image:
ImageSource("levels17.png", start=0, end=7200, fps=23.976)
ConvertToYUY2(matrix="PC.601")
v1=VideoScope("bottom").Subtitle("after ConvertToYUY2()")
v2=Levels(0,1,255,16,235,coring=false).VideoScope( "bottom").Subtitle("after levels()")
stackVertical(v1,v2).ConvertToRGB(matrix="PC.601")
I corrected the earlier post.
+ Reply to Thread
Results 91 to 109 of 109
-
Last edited by jagabo; 25th Apr 2010 at 11:00.
-
by increasing the gamma, I get a shaper edge. But some lines remains dark from the beginning to the end..
Lets take an example:
original:
after setting the black to the average luma of the 8 first pixels and the white to the average luma of the 8 last pixels:
And I used a gamma with a very high value (1000) but there is nothing to do.. I cannot get any bright pixel at the right.. And if I display the average luma, I get 16.5 for the first 8px and 25.25 for the last 8px. So by increasing the gamma to a certain point, I should be able to get some white pixel, shouldn't I ?Last edited by mathmax; 25th Apr 2010 at 14:07.
-
You should be using Levels(black, gamma, white, 0, 255, coring=false), or perhaps Levels(black, gamma, white, 16, 235, coring=false). The coring=false is needed so that the input pixels are not scaled from [16, 235] to [0, 255] before the levels conversion itself is performed.
-
yes. And I have to scale the image from [16, 235] to [0, 255] before getting average luma from the left and the right..
So the final script is:
Code:ImageSource("image.bmp") PointResize(width, height * 2) ConvertToYV12() Levels(16, 1, 235, 0, 255, coring=false) ProcessLine(last, 0) PointResize(width, height / 2) function ProcessLine(c, int n) { crop = c.Crop(4,n*2,28,2) newcrop = ScriptClip(crop, " black = int(AverageLuma(Crop(0,0,8,2))) #get the average luma of the left pixels white = int(AverageLuma(Crop(20,0,8,2))) #get the average luma of the right pixels margin = (white - black)/3 Levels(black + margin, 2, white - margin/2, 0, 255, coring=false) #adjust the level to make the left real black and right real white. ") Overlay(c, newcrop, 4, n*2) return (n < 239) ? ProcessLine(last, n + 1) : c }
- increase the gamma value from 1 to 2: at the limit of a scan line the pixels become gradually brighter. Setting a higher gamma should crush the luma of these pixels and sharpen the edge. I was even thinking of changing the gamma value according to the white value.. but I finally see no relevant argument to do this.
- the black has a lot of noise.. so some pixels are brighter. In order to keep them black, I raised the black to black + margin where margin = (white - black)/3.
These value are arbitrarily chosen according to my feeling. Any comments or other ideas would be greatly welcome.
Now, I'm facing a new problem.. when performing on a video, the script is very slow.. Any idea to make it more efficient? -
Try a low pass filter to reduce the noise and reducing the image to grayscale. You only need to do that on your test strip of course. And instead of Levels() try using ColorYUV().
Last edited by jagabo; 25th Apr 2010 at 20:31.
-
Thank you for these advices. I would need some explanations.
Try a low pass filter to reduce the noise and reducing the image to grayscale.
And instead of Levels() try using ColorYUV().
Any idea to make the script quicker? -
I'm just throwing out ideas. But you're right regarding grayscale -- if you're only working only with Y it doesn't matter.
-
Processing with ScriptClip is inherently slower, since the 'run-time' script must be parsed and evaluated afresh for every frame. Also, working with individual scanlines (or pairs as here) inevitably slows things down, as you have 240 chained invocations of your ProcessLine function.
One way to speed it up is to use StackVertical instead of Overlay to build up the result, with just a single Overlay at the end. Change ProcessLine to construct just the vertical strip to be replaced, as follows:
Code:function ProcessLine(clip c, int n) { crop = c.Crop(4,n*2,28,2) newcrop = ScriptClip(crop, " black = int(AverageLuma(Crop(0,0,8,2))) #get the average luma of the left pixels white = int(AverageLuma(Crop(20,0,8,2))) #get the average luma of the right pixels margin = (white - black)/3 Levels(black + margin, 2, white - margin/2, 0, 255, coring=false) #adjust the level to make the left real black and right real white. ") return (n < 239) ? StackVertical(newcrop, ProcessLine(c, n + 1)) : newcrop }
Overlay(last, ProcessLine(last, 0), 4, 0)
[or simply Overlay(ProcessLine(0), 4, 0)] -
ya it's faster
And is there any other tricks to speed things up even more? Should I necessarily use a runtime function? Maybe it's possible pre-build ScriptClip().. or the full script.
http://www.softpedia.com/get/Multimedia/Video/Other-VIDEO-Tools/AVISynthesizer.shtmlLast edited by mathmax; 26th Apr 2010 at 09:43.
-
Short of writing your own customised plugin to do the job, I don't think there's much more you can do to speed it up, as the slowness is inherent in the problem. ScriptClip is needed, since the processing is different for each frame, and processing by scanline inevitably requires taking each frame apart and putting it back together again.
Since Crop and StackHorizontal are relatively fast operations, a minor change would be to replace the outer Overlay by a StackHorizontal of left part (pixels 0-3), new middle (4-31), and right part (32-end), but since that's only done once per frame, the savings will not be so great.
What I mean is replace Overlay(ProcessLine(0), 4, 0) by
StackHorizontal(Crop(0, 0, 4, 0), ProcessLine(0), Crop(32, 0, 0, 0))
I'm not familiar with AviSynthesizer, but I doubt if it could generate faster scripts than hand-crafted ones.Last edited by Gavino; 26th Apr 2010 at 14:31. Reason: 'middle' part is pixels 4-31
-
ok. Thank you. The script is not very fast but it's acceptable..
Now, I've to detect the average position of the left edge. And the "crop" clip must be centered around this limit in order to be sure the eight pixels from the left are in the black strip and the 8 last pixels are in the scan lines.
Here you can see that there are significant differences between the frames:
How would you establish the average position of this limit? -
The simplest thing would be to do it by eye, stepping through a representative range of frames one at a time in an editor. Note - AvsP will show you the coordinates of the pixel under the mouse pointer.
One way to do it in a script might be to take the AverageLuma of successively wider vertical strips until the value is greater than some threshold. I haven't fully thought this through and I'll leave you to work out the details, if indeed it's practical at all.
BTW there was an error in my last post, now corrected. The replaced vertical strip is of course 28 pixels wide, not 8 as I had there. -
The problem is how to store the averageluma value of a vertical strip in a variable since the function local variables do not exist when the run-time script is evaluated..
-
Perhaps a global variable could be used?
If you have an outline script in mind, post it here and I will see if and how it might be made to work. -
Thinking further about this, I think the script logic needs to be something like:
Code:for each frame: determine edge position for each scanline: fix levels for pixels around this edge replace edge pixels
Code:global thresh = ??? # luma threshold to determine edge function FindEdge(clip c, int current_frame, int x) { (x >= 50 || AverageLuma(c.Crop(2, 0, x-2, 0)) > thresh) ? x : FindEdge(c, current_frame, x+2) } function ProcessLine(clip c, int current_frame, int edge, int n) { c.Crop(edge-14,n*2,28,2) # get section around edge for scanline n black = int(AverageLuma(Crop(0,0,8,2))) #get the average luma of the left pixels white = int(AverageLuma(Crop(20,0,8,2))) #get the average luma of the right pixels margin = (white - black)/3 newcrop = Levels(black + margin, 2, white - margin/2, 0, 255, coring=false) #adjust the level to make the left real black and right real white. return (n < 239) ? StackVertical(newcrop, ProcessLine(c, current_frame, edge, n + 1)) : newcrop } ... ScriptClip(""" edge = FindEdge(current_frame, 16) fixed = ProcessLine(current_frame, edge, 0) StackHorizontal(Crop(0, 0, edge-14, 0), fixed, Crop(edge+14, 0, 0, 0)) """)
Passing current_frame to the functions is a hack to allow AverageLuma to work inside a function - this could be avoided using GRunT.
The recursions could be replaced by for/while loops using GScript. -
Thank you very much for this.
And sorry for my late answer.. I wasn't at home the last days.
By taking a strip of 36px width and setting the black with the 6px at the left and the white with the 6px at the right, I get satisfying result for all frames without having to detect the average position of the edge.
Now I'll try your script to see if it's better.
I would like to do the same with the right edges of the frames (between position 684 and 720) but I cannot use StackVertical() because it'll stack the strip at the left hand side. I could use overlay()... but it'll be slower. How would you get around this problem? -
I don't see the problem, the logic is the same as before, only the crop position is changed.
We can write a function similar to the ProcessLine function from post #98 to handle the right edge:
Code:function ProcessLineRt(clip c, int n){ crop = c.Crop(684,n*2,36,2) # 36 x 2 px at right newcrop = ScriptClip(crop, " white = int(AverageLuma(Crop(0,0,6,2))) #get the average luma of the left pixels black = int(AverageLuma(Crop(30,0,6,2))) #get the average luma of the right pixels margin = (white - black)/3 Levels(black + margin, 2, white - margin/2, 0, 255, coring=false) #adjust the level to make the left real white and right real black ") return (n < 239) ? StackVertical(newcrop, ProcessLineRt(c, n + 1)) : newcrop }
StackHorizontal(ProcessLine(0), Crop(36, 0, -36, 0), ProcessLineRt(0)) -
delete
Last edited by Cherbette; 2nd Nov 2011 at 15:47. Reason: started own thread
Similar Threads
-
Improve a old VHS Capture
By cd090580 in forum RestorationReplies: 1Last Post: 5th Nov 2011, 14:33 -
Can a digital video stablizer improve non-copywrited VHS tapes?
By Regor21 in forum Newbie / General discussionsReplies: 10Last Post: 22nd Jul 2010, 11:12 -
Improve 15 year old VHS quality when capturing
By diegolaz in forum Capturing and VCRReplies: 6Last Post: 12th Jul 2009, 14:17 -
VHS to DVD - is there any way I can improve quality of conversion?
By rairjordan in forum Capturing and VCRReplies: 21Last Post: 13th Feb 2009, 12:32 -
How to improve dark VHS picture?
By rbatty11 in forum RestorationReplies: 15Last Post: 11th Sep 2007, 18:57