显示模板匹配结果

Showing result of template matching

我 运行 在 Halide 中进行模板匹配时遇到另一个问题(原始 link 已解决问题:

现在我试图在得分最低的位置(表示最佳匹配)绘制一个矩形。

模板匹配部分:

Image<float> source = load_image("C:\Users\Admin\Desktop\templateMatchingOpenCV\clip\clip2.png");
Image<float> templ = load_image("C:\Users\Admin\Desktop\templateMatchingOpenCV\clip\object3.png");
Var x, y, xt, yt, x_outer, y_outer, x_inner, y_inner, tile_index;

RDom r(0, templ.width(), 0, templ.height());

Func limit, comparesqdiff, comparesqdiffnorm, compareccorr;
limit = BoundaryConditions::constant_exterior(source, 1.0f);

Expr function = sum(Halide::pow(templ(r.x, r.y) - limit(x + r.x, y + r.y), 2)) / (templ.width()*templ.height());
comparesqdiff(x, y) = sum(Halide::pow(templ(r.x, r.y) - limit(x + r.x, y + r.y), 2)) / (templ.width()*templ.height());
Image<float> outputsqdiff;

comparesqdiff.tile(x, y, x_outer, y_outer, x_inner, y_inner, 64,64).fuse(x_outer, y_outer, tile_index).vectorize(x_inner).unroll(y_inner).parallel(tile_index);

comparesqdiff.compile_jit();

现在我很清楚我应该用来查找最低分数位置的函数是 argmin,但我不太明白它是如何使用的。我也知道绘图方法会覆盖像素下方和右侧的所有内容,但我还没有涉及到那部分。

绘制矩形部分:

RDom wholeImage(0, source.width() - templ.width(), 0, source.height() - templ.height());

Tuple coords = argmin(r, function, "argmin");

Func show;

show(x, y) = select(x >= coords[0] && y >= coords[1] && x <= coords[0] + templ.width() && y <= coords[1] + templ.height(), 0, limit(x, y));

Image<float> test(source.width(), source.height());

test = show.realize(source.width(), source.height());

提前谢谢你。

argmin 缩减迭代您的 RDom,比较值并保持最低值和值的位置。

Halide::RDom matchDom
    ( 0, templ.width ()
    , 0, templ.height()
    );
Halide::RDom searchDom
    ( 0, source.width () - templ.width ()
    , 0, source.height() - templ.height()
    );
Halide::Expr score = Halide::sum
    ( matchDom 
    , Halide::pow
        ( templ( matchDom.x, matchDom.y )
        - limit( searchDom.x + matchDom.x
               , searchDom.y + matchDom.y)
        , 2
        )
    )
    / ( templ.width() * templ.height() );
Halide::Tuple searchBest = Halide::argmin( searchDom, score );
Halide::Func best;
best(_) = searchBest(_);

然后你可以调用best.realize()得到一个Halide::Realization。该实现将包含 3 个缓冲区,每个缓冲区都有一个值:最低值的 x 坐标、最低值的 y 坐标和最低值。

Halide 不是绘制几何形状的最佳工具。为了我的钱,使用 for 循环将像素写入图像会更容易。

ASKER 的编辑:添加标记最佳结果,它使用答案的方法找到最佳分数

Realization re = best.realize();

Func draw("draw");

Image<int> x_coordinate(re[0]);
Image<int> y_coordinate(re[1]);
Image<float> s(re[2]);

draw(x,y) = select(x == x_coordinate(0, 0) || y == y_coordinate(0,0) || x == (x_coordinate(0,0) + templ.width()) || y ==  (y_coordinate(0,0) + templ.height()), 0.0f, source(x,y));

Image<float> drawTest;

drawTest = draw.realize(source.width(), source.height());

save_image(drawTest, path);

绘图示例:

来源:

模板:

结果:

提问者的编辑2:

做到了,所以它只绘制了比赛周围的矩形

draw(x, y) = select((x == x_coordinate(0, 0) && (y >= y_coordinate(0, 0) && y <= y_coordinate(0, 0) + templ.height())) ||
    ((x == x_coordinate(0, 0) + templ.width()) && (y >= y_coordinate(0, 0) && y <= y_coordinate(0, 0) + templ.height())) ||
    (y == y_coordinate(0, 0) && (x >= x_coordinate(0, 0) && x <= x_coordinate(0, 0) + templ.width())) ||
    ((y == y_coordinate(0, 0) + templ.height()) && (x >= x_coordinate(0, 0) && x <= x_coordinate(0, 0) + templ.width())), 0.0f, limit(x, y));

draw.tile(x, y, x_outer, y_outer, x_inner, y_inner, 64, 64).fuse(x_outer, y_outer, tile_index).vectorize(x_inner).unroll(y_inner).parallel(tile_index);

结果: