Log in

View Full Version : Interleaving pixels from multiple clips


pbristow
6th August 2012, 17:12
I had a search for this, but either I'm using the wrong search terms or it's not out there... Has anyone produced a plugin that can do this, reasonably efficiently?

Let me explain in more detail what I'm after: At a minimum, given a pair of clips A and B, I want to be able to combine them into a double-width clip where the first column of pixels is the first column from A, the 2nd is the first column from B, the third is the 2nd column from A, and so on.

Now, I know this can be done by using a combination of Rotate, Interleave, AssumeFieldBased and Weave (with a final rotate to get things back the right way up) - i.e. treating the two clips as if they were the separated field streams from an interlaced source -but that's quite slow and clumsy.

Eventually, what I'd like to be able to do is build up a double width, double-height clip from four source clips (A,B,C,D) with pixels arranged as follows:

(Notation format is: CLIP(row,column) )

A(1,1), B(1,1), A(1,2), B(1,2), A(1,3), B(1,3)
C(1,1), D(1,1), C(1,2), D(1,2), C(1,3), D(1,3)
A(2,1), B(2,1), A(2,2), B(2,2), A(2,3), B(2,3)
C(2,1), D(2,1), C(2,2), D(2,2), C(2,3), D(2,3)

Again, this can be done by combining two separate operations, one vertical and one horizontal, using Rotate() to switch the orientation, but it would surely be much more efficient to do it directly in C (let alone assembler!). Has anyone already produced anything like that?


(Hmmm... I just had an idea that *might* be quicker than what I've got... PointResize both clips to double width (or height, as appropriate), and then mt_merge them using a mask of single-pixel black and white stripes...?)

jmac698
6th August 2012, 17:15
mask and weave would probably work well.
There's a direct way; pointresize the 4 clips, then merge them together.
The mask requires a grid of dots at different offsets; this should be easy with lutspa.
Sounds like you're faking a Bayer pattern :)


#Generate a sample picture
blankclip(pixel_type="YV12", color_yuv=$EB8080)
pointresize(width*2,height*2)#fat pixels

#Generate background mask
zero=mt_lut(expr="0",chroma="process")

#Create masks for each position
gridsize=4#for YV12 fat pixels
a_mask=dotgrid(gridsize/2,gridsize/2,gridsize,gridsize,0,0)#0 0
b_mask=dotgrid(gridsize/2,gridsize/2,gridsize,gridsize,gridsize/2,0)#1 0
c_mask=dotgrid(gridsize/2,gridsize/2,gridsize,gridsize,0,gridsize/2)#0 1
d_mask=dotgrid(gridsize/2,gridsize/2,gridsize,gridsize,gridsize/2,gridsize/2)#1 1

#Extract rgb colors from original picture
r=converttorgb.showred.rgbadjust(g=0,b=0).converttoyv12
g=converttorgb.showgreen.rgbadjust(r=0,b=0).converttoyv12
b=converttorgb.showblue.rgbadjust(r=0,g=0).converttoyv12

maskmerge(zero,b,a_mask)
maskmerge(last,g,b_mask)
maskmerge(last,g,c_mask)
maskmerge(last,r,d_mask)


function dotgridexpr(int xsize, int ysize, int xspacing, int yspacing, int xoffset, int yoffset, int scaledivisor) {
#Generate masktools expression for squares in a gride
#x xspacing % xsize xoffset + < x xspacing % xoffset >= & ... & maskon maskoff ?
maskon=255
maskoff=0
xsize=xsize/scaledivisor
ysize=ysize/scaledivisor
xspacing=xspacing/scaledivisor
yspacking=yspacing/scaledivisor
xoffset=xoffset/scaledivisor
yoffset=yoffset/scaledivisor
a="x "+string(xspacing)+" % "+string(xsize+xoffset)+" < x "+string(xspacing)+" % "+string(xoffset)+" >= &"
b="y "+string(yspacing)+" % "+string(ysize+yoffset)+" < y "+string(yspacing)+" % "+string(yoffset)+" >= &"
a+" "+b+" & "+string(maskon)+" "+string(maskoff)+" ?"
}

function dotgrid(clip template, int xsize, int ysize, int xspacing, int yspacing, int xoffset, int yoffset) {
#make a dotgrid
template
yexpr=dotgridexpr(xsize, ysize, xspacing, yspacing, xoffset, yoffset, 1)
uexpr=dotgridexpr(xsize, ysize, xspacing, yspacing, xoffset, yoffset, 2)
vexpr=uexpr
mt_lutspa(mode="absolute", yexpr=yexpr,uexpr=uexpr,vexpr=vexpr,chroma="process")
}

function maskmerge(clip v1, clip v2, clip mask) {
#Because I can't get mt_merge to work :(
mt_lutxyz(v1,v2,mask,expr="z 255 = y x ?",chroma="process")
}

Something is buggy, could be AvsP or something else... does this work for anyone?