0

I'm trying to create a template matching program that's using the following formula to determine the fit between the template and the image:

formula

my code is following:

Halide::Var x, y, xt, yt;
Halide::RDom r(0, t.width(), 0, t.height());
Halide::Func limit, compare;
limit = Halide::BoundaryConditions::constant_exterior(input,255);
compare(x, y) = limit(x,y);
compare(x, y) = Halide::cast<uint8_t>(Halide::pow(t(0 + r.x, 0 + r.y) - limit(x + r.x, y + r.y),2));

Halide::Image<uint8_t> output(input.width(),input.height());
output = compare.realize(input.width(),input.height());

After executing the following code the result image is shifted like in the example:

Original image: Original image

Template: Template

Result: Result

How can I prevent the image from shifting?

Rok
  • 476
  • 1
  • 5
  • 12

2 Answers2

1

Not sure what the types of t and input are, so the following might overflow, but I think you want something like:

Halide::Var x, y, xt, yt;
Halide::RDom r(0, t.width(), 0, t.height());
Halide::Func limit, compare;
limit = Halide::BoundaryConditions::constant_exterior(input,255);
compare(x, y) = limit(x,y);
compare(x, y) = Halide::cast<uint8_t>(sum(Halide::pow(t(r.x, r.y) - limit(x + r.x - t.width()/2, y + r.y - t.height()/2),2))/(t.width()*t.height()));

Halide::Image<uint8_t> output(input.width(),input.height());
output = compare.realize(input.width(),input.height());
Andrew Adams
  • 1,396
  • 7
  • 3
  • your solution does work (except I had to remove the initial `compare(x,y) = limit(x,y)` part) but can you please explain why you're dividing the sum with the product of the template dimensions? – Rok Aug 22 '16 at 07:39
1

There is no sum. You are only storing the squared difference of the lower right pixel of the template image. There's some other things too, which I commented on:

Halide::Var x, y, xt, yt;
Halide::RDom r(0, t.width(), 0, t.height());
Halide::Func limit, compare;

// There's no point comparing the template to pixels not in the input.
// If you really wanted to do that, you should start at
// -t.width(), -t.height() and wd, ht will be plus the template size
// instead of minus.
int wd = input.width () - t.width ();
int ht = input.height() - t.height();

// constant_exterior returns a Func.
// We can copy all dimensions with an underscore.
limit(_) = Halide::BoundaryConditions::constant_exterior(input,255)(_) / 255.f;

Func tf;
tf(_) = t(_) / 255.f;

// Not necessary now and even so, should have been set to undef< uint8_t >().
// compare(x, y) = limit(x,y);

// Expr are basically cut and pasted to where they are used.
Expr sq_dif = Halide::pow(tf(r.x, r.x) - limit(x + r.x, y + r.y), 2);
Expr t_count = t.width() * t.height();
Expr val = Halide::sum(sq_dif) / t_count;

compare(x, y) = Halide::cast<uint8_t>(Halide::clamp(255 * val, 0, 255));

// The size of output is set by realize().
Halide::Image<uint8_t> output;
output = compare.realize(wd, ht);
Khouri Giordano
  • 796
  • 3
  • 9