VideoHelp Forum
+ Reply to Thread
Results 1 to 22 of 22
Thread
  1. Member Ninelpienel's Avatar
    Join Date: Dec 2013
    Location: Germany
    Search PM
    Hello, I have a video whit yellow hardcodet subtitles . Can I change the color form these subtitles whit a AviSynth plug-in? It is a
    striking yellow (colorcode: fff807).

    greeting
    Quote Quote  
  2. You can use ColorKeyMask() (documented in the Layers() section of the AviSynth manual) to build a mask from the yellow subs then overlay a different color there with Tweak(hue=x), Tweak(sat=0.0), etc.
    Quote Quote  
  3. Member Ninelpienel's Avatar
    Join Date: Dec 2013
    Location: Germany
    Search PM
    Thx, but can you write the comand for me complete.
    Subcolor: fff807
    New color: ffffff

    And can I define the ColorKeyMask for a particular area?
    Quote Quote  
  4. Upload a short video sample.
    Quote Quote  
  5. Member
    Join Date: Sep 2007
    Location: Canada
    Search Comp PM
    Another option is to use maskhs() included with avisynth 2.6.x . You can crop to the region of interest, and overlay that region (e.g if the subs only occur in the lower 1/4 of the picture, crop to that region). Since the replacement color is "white", you can use the mask itself as the replacement

    As usual, play with the values to customize your results to your tastes. You may want to blur the mask, or expand the mask using masktools, or use some AA. You may have to adjust the crop region


    Code:
    orig=ffvideoSource("cut.mkv")
    
    orig
    ConvertToYV24()
    crop(0,800,0,0,true)
    maskhs(starthue=155, endhue=185, minsat=50, coring=false)
    msk=last
    
    overlay(orig, msk, y=800, mask=msk)
    Quote Quote  
  6. I didn't know about MaskHS(). That will probably work better than ColorKeyMask() because subtitles are usually antialiased. To get enough coverage with ColorKeyMask() requires quite a lot of variation from the selected RGB values making the mask match a lot of other stuff in the picture.
    Quote Quote  
  7. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    Code:
    orig=FFVideoSource("E:\cut (1).mkv").Trim(568,626)
    
    orig
    deen("a2d",7,120,80)
    ConvertToYV24()
    crop(0,800,0,0,true)
    maskhs(starthue=160,endhue=180,maxsat=100,minsat=50,coring=false)
    ConvertToYV12()
    Blur(1.58)
    FFT3DFilter(Sigma=6)
    ColorYUV(gain_y=1024)
    ColorYUV(off_y=-60)
    ColorYUV(gain_y=1024)
    addborders(0,800,0,0)
    msk=last
    
    overlay(orig, orig.GreyScale().ColorYUV(cont_y=50), mask=msk)
    Eliminating false positives would be difficult, the fact that the subtitles are surrounded by black would be the best hope there, assuming nothing with yellow surrounded by black appears in the background at some point.
    Last edited by ndjamena; 16th May 2014 at 12:01. Reason: Sigma was too high. Theft is fun!
    Quote Quote  
  8. Member
    Join Date: Sep 2007
    Location: Canada
    Search Comp PM
    Yes, false positives are impossible to treat automatically. Any non sub area with high yellow saturation in the crop region will be affected

    Or another approach would be if you can find subs on various subtitle sites for this, is adjust them in aegisub and overlay them. That should give "perfect" results
    Quote Quote  
  9. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    We need a modified version of the 'fill' button in paint.

    Or it might already be perfect, I guess we need him to try it out on the full video.
    Quote Quote  
  10. Here's a variation I came up with using a greyscale (contrast enhanced) version of the video as the replacement color:

    Code:
    ffVideoSource("cut.mkv") 
    mask=MaskHS(160,180, 100,80).mt_expand().BilinearResize(last.width, last.height)
    overlay(last, GreyScale().ColorYUV(cont_y=50), 0, 0, mask)
    Click image for larger version

Name:	sample.jpg
Views:	17
Size:	122.8 KB
ID:	25221

    You'll need mt_masktools to use mt_expand(). If you want to use the single threaded Expand() (in the Masktools package) instead of mt_expand(), ConvertToYV12() before Expand().

    Code:
    mask=MaskHS(160,180, 100,80).ConvertToYV12().Expand().BilinearResize(last.width, last.height)
    Last edited by jagabo; 16th May 2014 at 10:21.
    Quote Quote  
  11. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    OK, I only just figured out how to make masks and I couldn't figure out how to fill them out (grow the white area or... expand). Is something in there what I was looking for?
    Quote Quote  
  12. My scripts use mt_expand() or Expand().
    Quote Quote  
  13. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    Grrrrr. I've already read the MaskTools v2 instructions and they're gibberish, I just googled for a tutorial and stumbled across the original MaskTool instructions. Now it makes sense.

    I used Deen in case there were small objects of the same yellow, it's the only way I can think of the cut into them and break them down a bit. I added FFT3DFilter to hopefully weed out any small particles. Any more than sigma 6 and it affects the first frame of a subtitle though. Doing anything about large objects seems impossible though. New at this.
    Quote Quote  
  14. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    I know no one cares anymore, but I need to learn somehow:

    Code:
    SetMemoryMax(1024)
    
    function KillTextYellow (clip c, int "Placement")
    {
    Placement=default(Placement, 0)
    Crpd=c.crop(0,Placement,0,0,true)
    BMask=Crpd.mt_binarize(26, true).mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand()
    DMask=Crpd.deen("a2d",7,120,80).ConvertToYV24().maskhs(160,180,100,50,coring=false).ConvertToYV12().Blur(1.58).FFT3DFilter(Sigma=6).ColorYUV(gain_y=1024).ColorYUV(off_y=-60).ColorYUV(gain_y=1024)
    YMask=Crpd.ConvertToYV24().maskhs(160,180,100,50,coring=false).ConvertToYV12().mt_binarize(100, false).mt_expand().ColorYUV(gain_y=1024).ColorYUV(off_y=-60).ColorYUV(gain_y=1024)
    FMask = mt_logic(mt_logic(BMask, DMask, "and"), YMask, "and")
    return overlay(c, Crpd.GreyScale().ColorYUV(cont_y=50), mask=FMask, y=Placement)
    }
    
    FFVideoSource("E:\cut (1).mkv")
    KillTextYellow(800)
    It's a bit slow but hopefully it reduces false positives down to almost nothing.

    Once you already have a fairly good idea of what they're supposed to be saying the MT2 instructions slowly start making sense.

    -Edit- If you find you have yellow spots in the middle of some letters, add another mt_expand and mt_inpand to the BMask Line.
    Last edited by ndjamena; 17th May 2014 at 08:04.
    Quote Quote  
  15. Originally Posted by ndjamena View Post
    I know no one cares anymore, but I need to learn somehow:

    Code:
    SetMemoryMax(1024)
    
    function KillTextYellow (clip c, int "Placement")
    {
    Placement=default(Placement, 0)
    Crpd=c.crop(0,Placement,0,0,true)
    BMask=Crpd.mt_binarize(26, true).mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand()
    DMask=Crpd.deen("a2d",7,120,80).ConvertToYV24().maskhs(160,180,100,50,coring=false).ConvertToYV12().Blur(1.58).FFT3DFilter(Sigma=6).ColorYUV(gain_y=1024).ColorYUV(off_y=-60).ColorYUV(gain_y=1024)
    YMask=Crpd.ConvertToYV24().maskhs(160,180,100,50,coring=false).ConvertToYV12().mt_binarize(100, false).mt_expand().ColorYUV(gain_y=1024).ColorYUV(off_y=-60).ColorYUV(gain_y=1024)
    FMask = mt_logic(mt_logic(BMask, DMask, "and"), YMask, "and")
    return overlay(c, Crpd.GreyScale().ColorYUV(cont_y=50), mask=FMask, y=Placement)
    }
    
    FFVideoSource("E:\cut (1).mkv")
    KillTextYellow(800)
    It's a bit slow but hopefully it reduces false positives down to almost nothing.

    Once you already have a fairly good idea of what they're supposed to be saying the MT2 instructions slowly start making sense.

    -Edit- If you find you have yellow spots in the middle of some letters, add another mt_expand and mt_inpand to the BMask Line.
    It's leaving some blocks of yellow in the OP's sample.

    Name:  blocks.jpg
Views: 106
Size:  24.7 KB
    Quote Quote  
  16. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    I've saved it as an AVI and have gone through every frame and I'm not seeing that. Which frame are you getting that from?

    -Edit- Maybe you have a different version of mt_masktools because it looks like BMask isn't reaching the center of those joins. Add another mt_expand and another mt_inpand. It's suppose to expand the black mask to fill in the space occupied by the Yellow colour, then shink it to make external black lines disappear completely. Only yellow contained within a black outline should survive.
    Quote Quote  
  17. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    Crud, that line is being cut off, the VDUB window is taking up too much space, I'll have to figure out how to get it to show the entire image on screen.

    -Edit- 75%, OK I see it now :P

    -Edit2- I don't suppose there's an AVISynth filter that will run another filter nth number of times???
    Quote Quote  
  18. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    Grr, I've added 2 more layers and there's still some yellow left, I'll have to look at the masks separately again to figure out what's going on.

    -Edit- *sigh* Now that I can see the entire screen, I can see the second mask is failing as well. I was wondering why they were talking and no subtitles were showing!
    Last edited by ndjamena; 17th May 2014 at 08:25.
    Quote Quote  
  19. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    Apparently the corner wasn't solid enough to stop deen from penetrating it. The second mask would have given a slightly more accurate result in certain situations but I can't figure out how to fix the corner bleed so I've removed it. Anyway, unless I've done something else really stupid, this version works:

    Code:
    SetMemoryMax(1024)
    
    function KillTextYellow (clip c, int "Placement")
    {
    Placement=default(Placement, 0)
    Crpd=c.crop(0,Placement,0,0,true)
    BMask=Crpd.mt_binarize(26, true).mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_expand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_inpand()
    YMask=Crpd.ConvertToYV24().maskhs(160,180,100,50,coring=false).ConvertToYV12().mt_binarize(100, false).mt_expand()
    FMask = mt_logic(BMask, YMask, "and")
    return overlay(c, Crpd.GreyScale().ColorYUV(cont_y=50), mask=FMask, y=Placement)
    }
    
    FFVideoSource("E:\cut (1).mkv")
    KillTextYellow(800)
    Last edited by ndjamena; 17th May 2014 at 11:38.
    Quote Quote  
  20. Our scripts could easily be modified to change the color by replacing:

    Code:
    GreyScale().ColorYUV(cont_y=50)
    With something like

    Code:
    Tweak(hue=100, sat=1.2)
    Or some other color transform.
    Quote Quote  
  21. Member
    Join Date: Sep 2012
    Location: Australia
    Search Comp PM
    This is all I have so far.

    1: Every time I add a filter before deen the thing just crashes so I've commented it out for now
    2: There appears to be some colourless pixels around the edges, when you attempt to change the hue there are still a few whitish pixels left.

    Code:
    SetMemoryMax(1024)
    
    function mt_expand_recurse(clip c, int "thY", int "thC", string "mode", int "n", int "of")
    {
    	thY=default(thY, 255)
    	thC=default(thC, 255)
    	mode=default(mode, "square")
    	n=default(n, 1)
    	of=default(of, 1)
    	return n <= of ? mt_expand(c, thY, thC, mode).mt_expand_recurse(thY, thC, mode, n+1, of):c
    }
    
    function mt_inpand_recurse(clip c, int "thY", int "thC", string "mode", int "n", int "of")
    {
    	thY=default(thY, 255)
    	thC=default(thC, 255)
    	mode=default(mode, "square")
    	n=default(n, 1)
    	of=default(of, 1)
    	return n <= of ? mt_inpand(c, thY, thC, mode).mt_inpand_recurse(thY, thC, mode, n+1, of):c
    }
    
    function KillTextYellow (clip c, int "cut", int "sqr", int "ver", int "hor", int "fwd", int "bck", int "shk", int "spd", float "brt", int "mer", int "okn", int "clr")
    {
    	cut=default(cut, 0)
    	sqr=default(sqr, 8)
    	ver=default(ver, 24)
    	hor=default(hor, 20)
    	bck=default(bck, 18)
    	fwd=default(fwd, 18)
    	shk=default(shk, 1)
    	spd=default(spd, 7)
    	brt=default(brt, 0)
    	mer=default(mer, 1)
    	okn=default(okn, 5)
    	clr=default(clr, color_white)
    	Crp= cut > 0 ? c.crop(0,cut,0,0,true):c
    	WMask=Crp.mt_binarize(26, true)
    	Over=MergeChroma(Crp, BlankClip(Crp, color=clr))
    	ex="square"
    	SMask=WMask.mt_expand_recurse(mode=ex, of=sqr).mt_expand_recurse(of=mer).mt_inpand_recurse(of=mer).mt_inpand_recurse(mode=ex, of=sqr+shk)
    	ex="vertical"
    	VMask=WMask.mt_expand_recurse(mode=ex, of=ver).mt_expand_recurse(of=mer).mt_inpand_recurse(of=mer).mt_inpand_recurse(mode=ex, of=ver+shk)
    	ex="horizontal"
    	HMask=WMask.mt_expand_recurse(mode=ex, of=hor).mt_expand_recurse(of=mer).mt_inpand_recurse(of=mer).mt_inpand_recurse(mode=ex, of=hor+shk)
    	ex="0 0 -1 -1 1 1"
    	BMask=WMask.mt_expand_recurse(mode=ex, of=bck).mt_expand_recurse(of=mer).mt_inpand_recurse(of=mer).mt_inpand_recurse(mode=ex, of=bck+shk)
    	ex="0 0 -1 1 1 -1"
    	FMask=WMask.mt_expand_recurse(mode=ex, of=fwd).mt_expand_recurse(of=mer).mt_inpand_recurse(of=mer).mt_inpand_recurse(mode=ex, of=fwd+shk)
    	Mask=Crp.ConvertToYV24().maskhs(160,180,100,50,coring=false).mt_expand()
    	Mask=spd >= 2 ? mt_logic(Mask, SMask, "and"):Mask
    	Mask=spd >= 3 ? mt_logic(Mask, HMask, "and"):Mask
    	Mask=spd >= 4 ? mt_logic(Mask, VMask, "and"):Mask
    	Mask=spd >= 5 ? mt_logic(Mask, BMask, "and"):Mask
    	Mask=spd >= 6 ? mt_logic(Mask, FMask, "and"):Mask
    	return overlay(c, Over, mask=Mask, y=cut)
    }
    FFVideoSource("E:\cut (1).mkv")
    KillTextYellow(cut=800, shk=1, spd=6, clr=color_seagreen)
    Last edited by ndjamena; 31st May 2014 at 13:38.
    Quote Quote