我在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());
提前谢谢你。
答案 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);
绘图示例:
来源:
模板:
结果:
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);
结果: