2016-08-24 132 views
0

我遇到了另一个问题,同时使采用卤化物模板匹配(与解决问题的原文链接: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

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坐标。

卤化物不是绘制几何形状的最佳工具。对于我的钱来说,使用for循环将像素写入图像会更容易。

ASKER'S编辑:添加标记,它使用了答案的方法用于寻找最佳得分图的

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

提问者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

+0

嗯,如果我有其他的选择,我会选择他们,但此刻我正在为我的论文和OpenCV版本等这样做。 另外我假设我必须在模板匹配完成后添加argmin作为更新? 另外我想知道如何将像素的坐标转换为源图像,以使用它来绘制矩形,我已经知道如何去做。感谢您的回答 – Rok

+0

另外,我用于argmin的RDom基本上是模板匹配的整个结果图片 – Rok

+0

我会尝试您的建议并通过回报:) – Rok