I'm trying to display zebras (colorize totally black pixels one color and totally white pixels a second color) on a selected frame from a video using ffmpeg. Using an rgb lookup table expression I'm getting a workable solution:
lutrgb=r='if(eq(val,0),0,val)':g='if(eq(val,0),153,val)':b='if(eq(val,0),254,val)',lutrgb=r='if(eq(val,255),254,val)':g='if(eq(val,255),102,val)':b='if(eq(val,255),0,val)'
The problem with this expression is that it's testing each pixel for clipping by color, then modding only if that color component = 0 or 255. My video is largely black and white, but a slight pixel level color shift results in a two toned zebra pattern. You can see the two shades of blue in this sample zebra frame:
If I could test for the maxval for clipping into 0 and minval for 255 I would think this problem would be solved, but this code below doesn't work:
lutrgb=r='if(eq(maxval,0),0,val)':g='if(eq(maxval,0),153,val)':b='if(eq(maxval,0),254,val)',lutrgb=r='if(eq(minval,255),254,val)':g='if(eq(minval,255),102,val)':b='if(eq(minval,255),0,val)'
The if/then code for filters is poorly documented on the ffmpeg wiki. Any LUT experts out there?
r
values. But a pixel can have0
component without being black i.e.(0,25,44)
. You need to use the geq filter, which allows cross-referencing. I'll provide a sample invocation if you wish.lutrgb=r='if(eq(val,0),0,val)':g='if(eq(val,0),0,val)':b='if(eq(val,0),254,val)',lutrgb=r='if(eq(val,255),254,val)':g='if(eq(val,255),0,val)':b='if(eq(val,255),0,val)'
...but no customizable zebra colors =(