Log in

View Full Version : Subtract filter (A Subtitles Issue)


otakusama
25th September 2010, 06:44
Hi everyone, I have a doubt about how the Subtract filter works.

I have an "original textless videoclip" and a "hardsubtitled videoclip" which is recompressed from the original clip, so the only differences between the two clips are the almost unnoticeable recompression artifacts and the subtitles.

The point is, I want to isolate the subtitles, I mean, to have an output where the actual hardsubs are the only noticeable thing on the frame. Why would I want to do this? because it will be easier for the OCR Subrip function to detect the subtitles. It'd be very useful don't you think?

The Subtract filter was supposed to do that job, and it kind of does it but with unexpected/unwanted results. There is the grey background, slight recompression artifacts and the subs on it, that's OK... but I can see through the subtitles! Specially when there's motion, and they were supposed to be all solid color!

I've used in the script Subtract(vid1,vid2) and Subtract(vid2,vid1) (the only difference between both outputs is that one is color-inverted) and I've used the filter Overlay with modes "difference" and "subtract" with pretty much the same unwanted result. So, is there any way to have the actual solid-color subtitles from the videoclip? What do you suggest?

IanB
25th September 2010, 10:21
Your maths is confused.

Subtract() implements max(min(pixel1-pixel2+128, 255), 0)

You will need some clamping to get rid of the motion bleed through.

i.e. pixel = (pixel1-pixel2 > somelimit) ? 255 : 0

Which for lutxy could be something like :-

X Y - 10 > 219 * 16 +

Motenai Yoda
25th September 2010, 16:04
mt_makediff(video1,video1,u=128,v=128)

otakusama
26th September 2010, 01:59
thanks for the answers :)

mt_makediff(video1,video1,u=128,v=128)

mt_makediff(video2,video1,u=128,v=128) unfortunately makes no difference, it does more or less the same as Subtract(vid2,vid1).GreyScale()

Your maths is confused.

Subtract() implements max(min(pixel1-pixel2+128, 255), 0)

You will need some clamping to get rid of the motion bleed through.

i.e. pixel = (pixel1-pixel2 > somelimit) ? 255 : 0

Which for lutxy could be something like :-

X Y - 10 > 219 * 16 +

Ok I see that the Subtract() function should be modified to do what I want... but I don't really know how to exactly do it. I'm familiar with programing but I don't know how to particularly implement what you mention.

By the way, maybe I should've posted some examples:

Original Frame:
http://img201.imageshack.us/img201/8955/cliporig.jpg (http://img201.imageshack.us/i/cliporig.jpg/)

Subbed Frame:
http://img201.imageshack.us/img201/374/clipsubbed.jpg (http://img201.imageshack.us/i/clipsubbed.jpg/)

Subtract(orig,sub) you can see the portion of the original (inverted) frame through the subtitles which were supposed to be all solid-white
http://img214.imageshack.us/img214/6232/clipsubtractsuborig.jpg (http://img214.imageshack.us/i/clipsubtractsuborig.jpg/)

Subtract(sub,orig) you can see the portion of the original frame through the subtitles which are inverted and were supposed to be all solid-white with black borders
http://img819.imageshack.us/img819/6138/clipsubtractorigsub.jpg (http://img819.imageshack.us/i/clipsubtractorigsub.jpg/)

and this would be the result I am looking for, background color is irrelevant ( I edited it on MSPaint, I know is a rustic work but it's just an example)
http://img827.imageshack.us/img827/9445/portapapeles1s.jpg (http://img827.imageshack.us/i/portapapeles1s.jpg/)

IanB
26th September 2010, 03:33
You cannot do what you want with straight subtraction.

If a pixel in the white text is P1=200 and the corresponding pixel on say the girls apron is P2=150, then P1-P2=50.

If a pixel in the black text border is P1=20 and the corresponding pixel on say the girls apron is P2=150, then P1-P2=-130.

You probably want a function like :-

pixel = (abs(P1-P2) > 5) ? P1 : 235

Using masktools you would do something like this :-

X Y - abs 5 > X 235 ?

otakusama
26th September 2010, 06:00
Ok I will make some tests, If there are any other suggestion please let me know, thanks

Motenai Yoda
27th September 2010, 02:09
threshold=5 #should be greater than 0
mt_lutxy(video1,video2,yexpr="x y - abs "+string(threshold)+" < 235 y ?",uexpr="x y - abs "+string(threshold)+" < 128 y ?",vexpr="x y - abs "+string(threshold)+" < 128 y ?",y=3,v=3,u=3)
or
threshold=5 #should be greater than 0
m=mt_lutxy(video1,video2,expr="x y - abs "+string(threshold)+" < 0 235 ?",y=3,v=3,u=3).mt_expand(u=3,v=3)
mt_lutxy(video2,m,yexpr="y 1 < 235 x ?",uexpr="y 1 < 128 x ?",vexpr="y 1 < 128 x ?",y=3,v=3,u=3)