显示模板匹配结果

时间:2016-08-24 11:11:51

标签: halide

我在Halide中进行模板匹配时遇到了另一个问题(已解决问题的原始链接:output shifted in template matching

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

模板匹配部分:

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());

提前谢谢你。

1 个答案:

答案 0 :(得分:1)

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&#39;编辑:添加标记最佳结果,使用答案的方法找到最佳分数

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);

绘图示例:

来源:

Source picture

模板:

Template picture

结果:

Result

ASKER&#39; S EDIT2:

这样做只会在比赛中绘制矩形

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);

结果:

Result2