computer_vision/matching.cpp
/*******************************************************
* Copyright (c) 2015, ArrayFire
* All rights reserved.
*
* This file is distributed under 3-clause BSD license.
* The complete license agreement can be obtained at:
* https://arrayfire.com/licenses/BSD-3-Clause
********************************************************/
#include <arrayfire.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace af;
array normalize(array a) {
float mx = af::max<float>(a);
float mn = af::min<float>(a);
return (a - mn) / (mx - mn);
}
void drawRectangle(array& out, unsigned x, unsigned y, unsigned dim0,
unsigned dim1) {
printf("\nMatching patch origin = (%u, %u)\n\n", x, y);
seq col_span(x, x + dim0, 1);
seq row_span(y, y + dim1, 1);
// edge on left
out(col_span, y, 0) = 0.f;
out(col_span, y, 1) = 0.f;
out(col_span, y, 2) = 1.f;
// edge on right
out(col_span, y + dim1, 0) = 0.f;
out(col_span, y + dim1, 1) = 0.f;
out(col_span, y + dim1, 2) = 1.f;
// edge on top
out(x, row_span, 0) = 0.f;
out(x, row_span, 1) = 0.f;
out(x, row_span, 2) = 1.f;
// edge on bottom
out(x + dim0, row_span, 0) = 0.f;
out(x + dim0, row_span, 1) = 0.f;
out(x + dim0, row_span, 2) = 1.f;
}
static void templateMatchingDemo(bool console) {
// Load image
array img_color;
if (console)
img_color = loadImage(ASSETS_DIR "/examples/images/square.png", true);
else
img_color = loadImage(ASSETS_DIR "/examples/images/man.jpg", true);
// Convert the image from RGB to gray-scale
array img = colorSpace(img_color, AF_GRAY, AF_RGB);
dim4 iDims = img.dims();
std::cout << "Input image dimensions: " << iDims << std::endl << std::endl;
// For visualization in ArrayFire, color images must be in the [0.0f-1.0f]
// interval
// extract a patch from input image
unsigned patch_size = 100;
array tmp_img =
img(seq(100, 100 + patch_size, 1.0), seq(100, 100 + patch_size, 1.0));
array result =
matchTemplate(img, tmp_img); // Default disparity metric is
// Sum of Absolute differences (SAD)
// Currently supported metrics are
// AF_SAD, AF_ZSAD, AF_LSAD, AF_SSD,
// AF_ZSSD, ASF_LSSD
array disp_img = img / 255.0f;
array disp_tmp = tmp_img / 255.0f;
array disp_res = normalize(result);
unsigned minLoc;
float minVal;
min<float>(&minVal, &minLoc, disp_res);
std::cout << "Location(linear index) of minimum disparity value = "
<< minLoc << std::endl;
if (!console) {
// Draw a rectangle on input image where the template matches
array marked_res = tile(disp_img, 1, 1, 3);
drawRectangle(marked_res, minLoc % iDims[0], minLoc / iDims[0],
patch_size, patch_size);
std::cout << "Note: Based on the disparity metric option provided to "
"matchTemplate function\n"
"either minimum or maximum disparity location is the "
"starting corner\n"
"of our best matching patch to template image in the "
"search image"
<< std::endl;
af::Window wnd("Template Matching Demo");
// Previews color image with green crosshairs
while (!wnd.close()) {
wnd.setColorMap(AF_COLORMAP_DEFAULT);
wnd.grid(2, 2);
wnd(0, 0).image(disp_img, "Search Image");
wnd(0, 1).image(disp_tmp, "Template Patch");
wnd(1, 0).image(marked_res, "Best Match");
wnd.setColorMap(AF_COLORMAP_HEAT);
wnd(1, 1).image(disp_res, "Disparity values");
wnd.show();
}
}
}
int main(int argc, char** argv) {
int device = argc > 1 ? atoi(argv[1]) : 0;
bool console = argc > 2 ? argv[2][0] == '-' : false;
try {
af::setDevice(device);
std::cout << "** ArrayFire template matching Demo **" << std::endl
<< std::endl;
templateMatchingDemo(console);
} catch (af::exception& ae) {
std::cerr << ae.what() << std::endl;
throw;
}
return 0;
}
af::dim4
Generic object that represents size and shape.
Definition: dim4.hpp:33
af::seq
seq is used to create sequences for indexing af::array
Definition: seq.h:46
AF_COLORMAP_DEFAULT
@ AF_COLORMAP_DEFAULT
Default grayscale map.
Definition: defines.h:454
af::info
AFAPI void info()
AF_COLORMAP_HEAT
@ AF_COLORMAP_HEAT
Heat map.
Definition: defines.h:459
af::setDevice
AFAPI void setDevice(const int device)
Sets the current device.
af::array
A multi dimensional data container.
Definition: array.h:35
af
Definition: algorithm.h:15
af::exception
An ArrayFire exception class.
Definition: exception.h:29
af::matchTemplate
AFAPI array matchTemplate(const array &searchImg, const array &templateImg, const matchType mType=AF_SAD)
C++ Interface for image template matching.
af::tile
AFAPI array tile(const array &in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)
AF_RGB
@ AF_RGB
3-channel RGB
Definition: defines.h:341
af::array::dims
dim4 dims() const
Get dimensions of the array.
af::colorSpace
AFAPI array colorSpace(const array &image, const CSpace to, const CSpace from)
C++ Interface wrapper for colorspace conversion.
af::loadImage
AFAPI array loadImage(const char *filename, const bool is_color=false)
C++ Interface for loading an image.
arrayfire.h
AF_GRAY
@ AF_GRAY
Grayscale.
Definition: defines.h:340
af::exception::what
virtual const char * what() const
Returns an error message for the exception in a string format.
Definition: exception.h:60
af::Window
Window object to render af::arrays.
Definition: graphics.h:37