2016-08-24 4 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 наименьшего значения и самое низкое значение.

Halide - не лучший инструмент для рисования геометрических фигур. Для моих денег было бы проще записывать пиксели в изображение с помощью цикла for.

EDIT Аскера: добавлена ​​маркировка лучшего результата, который использует метод ответа на вызов для нахождения лучшего результата

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'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

+0

Ну да, если бы у меня были другие альтернативы, я бы выбрал их, но в данный момент я делаю это для своей диссертации вместе с версией OpenCV и т. Д. Также я предполагаю, что мне нужно добавить argmin в качестве обновления после того, как будет выполнено сопоставление шаблонов? Плюс Мне интересно, как перенести координаты пикселя в исходное изображение, чтобы использовать его для рисования прямоугольника, который у меня уже есть идея о том, как это сделать. Спасибо за ответ – Rok

+0

Кроме того, RDom, который я использую для argmin, - это в основном полная картинка результата сопоставления шаблонов – Rok

+0

. Я попробую ваше предложение и отчитаюсь хотя бы :) :) – Rok

Смежные вопросы