File: matching.cpp

package info (click to toggle)
arrayfire 3.3.2%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 109,016 kB
  • sloc: cpp: 127,909; lisp: 6,878; python: 3,923; ansic: 1,051; sh: 347; makefile: 338; xml: 175
file content (120 lines) | stat: -rw-r--r-- 4,222 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <cstdio>
#include <arrayfire.h>
#include <cstdlib>

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);
        af::info();
        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;
}