VideoHelp Forum




+ Reply to Thread
Results 1 to 17 of 17
  1. Hi,

    Does anyone know if there is an existing function for Avisynth that can be used to adjust the brightness of a specific vertical section of the frame?

    One option that came to mind is to try using ColorYUV(off_y = XXX) on a specific part of the frame, but perhaps there is already a ready-made implementation for this?

    I’ve attached a screenshot and a short AVI clip showing the problem I’m trying to fix.

    Image
    [Attachment 93471 - Click to enlarge]
    Image Attached Files
    Quote Quote  
  2. Code:
    LWLibavVideoSource("example-1.avi") 
    
    left = Crop(0,0,112,-0)
    mid = Crop(110,0,64,-0).ColorYUV(off_y=-3)
    right = Crop(174,0,-0,-0)
    
    StackHorizontal(left, mid, right)
    Using Overlay() and an alpha mask you could smooth out the edges.
    Quote Quote  
  3. Alternatively consider shifting the superblacks (y~10...13) up by ~3...4 steps.
    Quote Quote  
  4. Originally Posted by jagabo View Post
    Code:
    LWLibavVideoSource("example-1.avi") 
    
    left = Crop(0,0,112,-0)
    mid = Crop(110,0,64,-0).ColorYUV(off_y=-3)
    right = Crop(174,0,-0,-0)
    
    StackHorizontal(left, mid, right)
    Using Overlay() and an alpha mask you could smooth out the edges.
    Thanks! I have to study overlay & masking (Crop-approach was something I was familiar with, but using only that alone leaves visible lines)
    Quote Quote  
  5. Originally Posted by Sharc View Post
    Alternatively consider shifting the superblacks (y~10...13) up by ~3...4 steps.
    Thanks for noticing that . My capturing method is able to capture wider than 16-235. Also, if I have understood it right, levels over 16-235 causes problems only if I would do RGB -> YUV conversion somewhere at the process? (usually I try to keep captures in 16-235 range).
    Quote Quote  
  6. Y levels below 16 will all be crushed to 0, and levels above 235 will all be crushed at 255 upon a limited range YUV to full range RGB conversion. Note that TVs convert YUV to RGB that way for display so super black and super white details will be lost (there will be no visible detail in those areas).
    Quote Quote  
  7. Originally Posted by jagabo View Post
    Y levels below 16 will all be crushed to 0, and levels above 235 will all be crushed at 255 upon a limited range YUV to full range RGB conversion. Note that TVs convert YUV to RGB that way for display so super black and super white details will be lost (there will be no visible detail in those areas).
    So this has not been clear to me. I had understood that the conversation from YUV to RGB is not problematic but problems raises if there would be transformation back from RGB to YUV. Fortunately, I have generally kept the captures within the 16–235 range. I need to do some own testing to understand this a little bit better, generate somehow a gradient image from pure white (255) to pure black (0) and see what happens at different phases / converastion steps
    Last edited by Rolletus; 18th Aug 2026 at 07:20.
    Quote Quote  
  8. Good exercise, yes. Here is an example with Y (0....255), with waveform (luma values) shown on top.
    The YUV video has been decoded using the standard Rec.601 (TV) matrix, therefore you can't distinguish the bars Y<16 and Y>235 as these became RGB(0,0,0) or RGB(255,255,255) respectively, see 1st screenshot.
    If it had been decoded (viewed) using the PC.601 matrix one would see the superblacks and superwhite bars (2nd screenshot). Now Y and RGB are mapped 1:1 means Y 235 becomes RGB (235,235,235) and Y 16 becomes RGB(16,16,16) etc.
    What your TV actually does and how it treats YUV data depends on its renderer. Usually it uses "studio equations (aka studio matrix)" acc. ITU recommendations. So it may show (some of) the superblacks and superwhites, but these are normally intended as leeway for over-/undershoots and other imperfections. That's why staying in the 16....235 luma range is good practice - at least for the final distribution. This is shown with the last screenshot. Now one will see all bars using the standard Rec.601 matrix.

    Finally, what you eventually see on TV also depends on its brightnesss and contrast settings.
    Image Attached Thumbnails Click image for larger version

Name:	Y 0...255.png
Views:	9
Size:	46.5 KB
ID:	93479  

    Click image for larger version

Name:	Y 0...255_PC.png
Views:	4
Size:	47.8 KB
ID:	93481  

    Click image for larger version

Name:	Y 0...235_TV.png
Views:	4
Size:	88.6 KB
ID:	93482  

    Last edited by Sharc; 18th Aug 2026 at 13:08. Reason: 2nd and 3rd screenshot added
    Quote Quote  
  9. Originally Posted by Sharc View Post
    Good exercise, yes. Here is an example with Y (0....255), with waveform (luma values) shown on top.
    The YUV video has been decoded using the standard Rec.601 (TV) matrix, therefore you can't distinguish the bars Y<16 and Y>235 as these became RGB(0,0,0) or RGB(255,255,255) respectively, see 1st screenshot.
    If it had been decoded (viewed) using the PC.601 matrix one would see the superblacks and superwhite bars (2nd screenshot). Now Y and RGB are mapped 1:1 means Y 235 becomes RGB (235,235,235) and Y 16 becomes RGB(16,16,16) etc.
    What your TV actually does and how it treats YUV data depends on its renderer. Usually it uses "studio equations (aka studio matrix)" acc. ITU recommendations. So it may show (some of) the superblacks and superwhites, but these are normally intended as leeway for over-/undershoots and other imperfections. That's why staying in the 16....235 luma range is good practice - at least for the final distribution. This is shown with the last screenshot. Now one will see all bars using the standard Rec.601 matrix.

    Finally, what you eventually see on TV also depends on its brightnesss and contrast settings.
    Thanks about the explanation and the examples!

    I managed to adjust values to generate attached capture (VirtuaDub) for my own testing. My capture is displayed using "Rec.601 (TV) matrix" I assume
    Image Attached Thumbnails Click image for larger version

Name:	Histogram-1.jpg
Views:	12
Size:	44.1 KB
ID:	93486  

    Quote Quote  
  10. Member
    Join Date
    Aug 2018
    Location
    Wrocław
    Search PM
    VirtualDub always defaults to Rec601 when no color matrix information is available.
    However, tape captures are always Rec601 anyway.
    Quote Quote  
  11. Originally Posted by Rolletus View Post
    I managed to adjust values to generate attached capture (VirtuaDub) for my own testing. My capture is displayed using "Rec.601 (TV) matrix" I assume
    Yes. You can't distinguish the 2 superblacks and 2 superwhite bars because the YUV->RGB conversion using the standard Rec.601 matrix has mapped (shifted, clipped, crushed) these to RGB (0,0,0) and (255,255,255) respectively.
    Quote Quote  
  12. Originally Posted by rgr View Post
    However, tape captures are always Rec601 anyway.
    Yes, but there may be Y excursions extending into the superblack and superwhite area, depending on source, tape player, capture card, proc amp settings ...
    Not a problem as long as these are not clipped or getting mistreated.
    Quote Quote  
  13. Here's an example using the dark frames as a mask to darken the stripe away.

    Code:
    src = LWLibavVideoSource("example-1.avi", cache=false, prefer_hw=2) 
    
    #Average all the frames together to make an average frame
    src
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    ColorYUV(off_y=-12).ColorYUV(gain_y=2800)
    bmask = last
    
    # make a black frame
    black = BlankClip(src).ColorYUV(off_y=-255)
    
    # darken the original video using bmask to control how much
    Overlay(src, black, mask=bmask)
    
    # before and after, side by side
    StackHorizontal(src, last)
    
    # brighten the result so we can easily see the difference
    ColorYUV(gain_y=1000)
    Image
    [Attachment 93501 - Click to enlarge]


    Remove the last line then filter further as needed.

    No brighter frames were included so you may need to modify this for the reset of the video.
    Last edited by jagabo; 19th Aug 2026 at 16:43.
    Quote Quote  
  14. Nice.
    I think a last=src should follow the first line. SelectEven(), SelectOdd() .... needs an argument.
    Quote Quote  
  15. Here's a AviSynth script that builds a ramp of Y=0 to Y=255:

    Code:
    ######################################################
    
    function GreyRamp()
    {
       BlankClip(color=$000000, width=1, height=256, pixel_type="RGB32")
       StackHorizontal(last, last.RGBAdjust(rb=1, gb=1, bb=1))
       StackHorizontal(last, last.RGBAdjust(rb=2, gb=2, bb=2))
       StackHorizontal(last, last.RGBAdjust(rb=4, gb=4, bb=4))
       StackHorizontal(last, last.RGBAdjust(rb=8, gb=8, bb=8))
       StackHorizontal(last, last.RGBAdjust(rb=16, gb=16, bb=16))
       StackHorizontal(last, last.RGBAdjust(rb=32, gb=32, bb=32))
       StackHorizontal(last, last.RGBAdjust(rb=64, gb=64, bb=64))
       StackHorizontal(last, last.RGBAdjust(rb=128, gb=128, bb=128))
    }
    
    ######################################################
    
    GreyRamp()
    ConvertToYV12(matrix="PC.601") # use full range matrix to retain super blacks and super whites
    Sample RGB image before the conversion to YV12:
    Image
    [Attachment 93502 - Click to enlarge]
    Quote Quote  
  16. Originally Posted by Sharc View Post
    Nice.
    I think a last=src should follow the first line. SelectEven(), SelectOdd() .... needs an argument.
    Oh, yes. Cut and paste error. I'll fix the post.
    Quote Quote  
  17. Originally Posted by jagabo View Post
    Here's an example using the dark frames as a mask to darken the stripe away.

    Code:
    src = LWLibavVideoSource("example-1.avi", cache=false, prefer_hw=2) 
    
    #Average all the frames together to make an average frame
    src
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    Merge(SelectEven(), SelectOdd())
    ColorYUV(off_y=-12).ColorYUV(gain_y=2800)
    bmask = last
    
    # make a black frame
    black = BlankClip(src).ColorYUV(off_y=-255)
    
    # darken the original video using bmask to control how much
    Overlay(src, black, mask=bmask)
    
    # before and after, side by side
    StackHorizontal(src, last)
    
    # brighten the result so we can easily see the difference
    ColorYUV(gain_y=1000)
    Image
    [Attachment 93501 - Click to enlarge]


    Remove the last line then filter further as needed.

    No brighter frames were included so you may need to modify this for the reset of the video.
    Thanks, You are so helpful here! I will test this and try to study those parts of the script I'm not familiar with so that I can modify it if/when needed.
    Last edited by Rolletus; 20th Aug 2026 at 03:15.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!