openCL optical flow

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_t

to

__rd image2d_t

or

__wr image2d_t .

See OpenCL Optical Flow Port.

Still a work in progress, but fun.

Cheers, cybero

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.