Here's how to do optical flow in openCL. I converted this from an openGL shader here http://002.vade.info/?p=32
__kernel void optical_flow(read_only image2d_t srcImage1, read_only image2d_t srcImage2, write_only image2d_t dstImage, const float scale, const float offset, const float lambda, const float threshold) {
int2 coords = (int2)(get_global_id(0), get_global_id(1));
float4 a = read_imagef(srcImage1, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords);
float4 b = read_imagef(srcImage2, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords);
int2 x1 = (int2)(offset, 0.f);
int2 y1 = (int2)(0.f, offset);
//get the difference
float4 curdif = b - a;
//calculate the gradient
float4 gradx = read_imagef(srcImage2, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords+x1)
- read_imagef(srcImage2, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords-x1);
gradx += read_imagef(srcImage1, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords+x1)
- read_imagef(srcImage1, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords-x1);
float4 grady = read_imagef(srcImage2, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords+y1)
- read_imagef(srcImage2, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords-y1);
grady += read_imagef(srcImage1, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords+y1)
- read_imagef(srcImage1, CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, coords-y1);
float4 sqr = (gradx*gradx)+(grady*grady)+(float4)(lambda,lambda, lambda, lambda);
float4 gradmag = sqrt(sqr);
float4 vx = curdif*(gradx/gradmag);
float vxd = vx.x;//assumes greyscale
//format output for flowrepos, out(-x,+x,-y,+y)
float2 xout = (float2)(fmax(vxd,0.f),fabs(fmin(vxd,0.f)));
xout *= scale;
float4 vy = curdif*(grady/gradmag);
float vyd = vy.x;//assumes greyscale
//format output for flowrepos, out(-x,+x,-y,+y)
float2 yout = (float2)(fmax(vyd,0.f),fabs(fmin(vyd,0.f)));
yout *= scale;
float4 out = (float4)(xout, yout);
float cond = (float)isgreaterequal(length(out), threshold);
out *= cond;
write_imagef(dstImage, coords, out);
}

OpenCL Optical Flow
Marek, thanks for this example.
I have ported this to QC, a fairly trivial exercise, mostly being a matter of setting the terms in the kernel function from
read_only image2d_tto
__rd image2d_tor
__wr image2d_t.See OpenCL Optical Flow Port.
Still a work in progress, but fun.
Cheers, cybero
Post new comment