Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
224 views7 pages

Fast Template Matching with FFT

This document summarizes an approach to speed up cosine similarity template matching using the Fast Fourier Transform (FFT). It describes representing the template and image patches as Fourier transforms, computing their cross-correlation in the frequency domain using multiplication, and taking the inverse FFT to obtain cosine similarity values faster than directly computing correlations in the pixel domain. Pseudocode is provided to implement FFT-based cosine similarity template matching using OpenCV. By applying FFTs and working in the frequency domain, this approach reduces the complexity from O(NT) to O(N logN) where N is the number of pixels and T is the template size.

Uploaded by

Fatih TSP
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
224 views7 pages

Fast Template Matching with FFT

This document summarizes an approach to speed up cosine similarity template matching using the Fast Fourier Transform (FFT). It describes representing the template and image patches as Fourier transforms, computing their cross-correlation in the frequency domain using multiplication, and taking the inverse FFT to obtain cosine similarity values faster than directly computing correlations in the pixel domain. Pseudocode is provided to implement FFT-based cosine similarity template matching using OpenCV. By applying FFTs and working in the frequency domain, this approach reduces the complexity from O(NT) to O(N logN) where N is the number of pixels and T is the template size.

Uploaded by

Fatih TSP
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

HOME PAGE OF
HELIO PERRONI
FILHO
"THE FUTURE IS ALREADY HERE... IT'S
J U S T N O T E V E N LY D I S T R I B U T E D . "
(WILLIAM GIBSON)

M O N D A Y, D E C E M B E R 2 1 , 2 0 1 5

FFT-based cosine similarity for fast PA G E S

template matching Home


A common task in computer vision applications is Projects
template matching, the search for a comparatively Blog
small image patch – or more likely, its closest
approximation – in a larger image. In its simplest form,
this implies solving the following optimization: ARCHIVES

Where the similarity metric is defined


between a template and all patches
such that:

For an image with and (i.e.


the image is much larger than the template). A
common choice of similarity metric is cosine similarity,
which is defined as:

Cosine similarity is a reliable metric, but as defined


above its evaluation is rather costly. Combining
formulas , and gives:

1/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

Tweets by @xperroni
Helio Perroni Fi
@xperroni
Use .kateconfig for setting
per-project indentation and
Which is of time complexity – i.e. the tab settings in Kate.
size of the template times the size of the image. nhaehnle.blogspot.com.br/20
15/01/use-ka…
Depending on image and template sizes, the intended
use case (e.g. batch vs. real-time) or scale of the
template matching task (e.g. a couple dozen vs.
thousands of images), this may incur in prohibitive Helio Perroni Fi
processing costs. @xperroni

IBM Quantum Computing


platform open for general
Cosine similarity template matching can be sped up
access.
with application of the convolution theorem. First, let's research.ibm.com/quantum/
redefine formula as:

Helio Perroni Fi
@xperroni
Where: A repository of freely-licensed
art for FLOSS games.
opengameart.org

Embed View on Twitter

Looking into the three terms above, it's clear that


is constant for any given and can therefore be left
out of the computation. On the other hand, is just
the cross-correlation between and , which by the
convolution theorem can also be computed as:

Where is the fourier transform operator, the


inverse transform, the asterisk denotes the complex
conjugate, and is the Hadamard product
(element-wise multiplication) of the two transforms.

2/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

Likewise, can be computed as the cross-


correlation between and a window filter
:

The advantage of this approach is that algorithms


such as the Fast Fourier Transform (FFT) are of time
complexity , which depending on the
relative sizes of and may be faster than the
of the direct computation. Also the
Fourier transforms of and (if the same template will
be applied to several images) can be cached,
further saving up computation time.

Implementation

The C++ code below provides a basic implementation


of the method outlined above. It uses the popular
OpenCV library, with some further optimizations
particular to its implementation of the Fourier
transform, explained in the comments.

#include <opencv2/opencv.hpp>

static const cv::Scalar ONE(1);

static const cv::Scalar ZERO(0);

static const cv::Scalar WHITE(255, 255, 255);

// Fourier transform performance is not a monotonic functi


// size - matrices whose dimensions are powers of two are
// process, and multiples of 2, 3 and 5 (for example, 300
// also processed quite efficiently. Therefore it makes se
// data with zeros to get a bit larger matrix that can be
// faster than the original one.
cv::Size fit(const cv::Size &size)
{
return cv::Size(cv::getOptimalDFTSize(size.width),
cv::getOptimalDFTSize(size.height));
}

cv::Mat F_fwd(const cv::Mat &I, const cv::Size &size)


{
// Pad input matrix to given size.

3/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

cv::Mat P;
int m = size.height - I.rows;
int n = size.width - I.cols;
cv::copyMakeBorder(I, P, 0, m, 0, n, cv::BORDER_CONSTANT

// Compute Fourier transform for input data. The last ar


// informs the dft() function of how many non-zero rows
// so it can handle the rest of the rows more efficientl
// some time.
cv::Mat F;
cv::dft(P, F, 0, I.rows);

return F;
}

cv::Mat F_inv(const cv::Mat &F, const cv::Size &size)


{
// Compute inverse Fourier transform for input data. The
// argument informs the dft() function of how many non-z
// rows are expected in the output, so it can handle the
// of the rows more efficiently and save some time.
cv::Mat I;
cv::dft(F, I, cv::DFT_INVERSE + cv::DFT_SCALE, size.heig

return I(cv::Rect(0, 0, size.width, size.height));


}

cv::Mat C(const cv::Mat &T, const cv::Mat &I, const cv::Si


{
// Compute the Fourier transforms of template and image.
cv::Mat F_T = F_fwd(T, size);
cv::Mat F_I = F_fwd(I, size);

// Compute the cross correlation in the frequency domain


cv::Mat F_TI;
cv::mulSpectrums(F_I, F_T, F_TI, 0, true);

// Compute the inverse Fourier transform of the cross-co


// dismissing those rows and columns of the cross-correl
// matrix that would require the template to "roll over"
cv::Size clipped;
clipped.width = I.cols - T.cols;
clipped.height = I.rows - T.rows;
return F_inv(F_TI, clipped);
}

4/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

cv::Mat W(const cv::Mat &T)


{
return cv::Mat(T.size(), CV_64F, ONE);
}

cv::Point3f matchTemplate(const cv::Mat &T, const cv::Mat


{
// Compute the optimal size for DFT computing.
cv::Size size = fit(I.size());

//Compute the cross-correlation and normalizing matrix.


cv::Mat C_TI = C(T, I, size);
cv::Mat M_I = C(W(T), I.mul(I), size);

int i_s, j_s;


float r = 0;
int rows = C_TI.rows;
int cols = C_TI.cols;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
float v = C_TI.at(i, j) / sqrt(M_I.at
if (r < v)
{
r = v;
i_s = i;
j_s = j;
}
}
}

return cv::Point3f(j_s, i_s, r);


}

cv::Mat L(const cv::Mat &I)


{
cv::Mat L_I, L_F;
cv::cvtColor(I, L_I, CV_BGR2GRAY);
L_I.convertTo(L_F, CV_64F);
return L_F;
}

int main(int argc, char *argv[])

5/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

{
cv::Mat T = cv::imread(argv[1]);
cv::Mat I = cv::imread(argv[2]);

cv::Point3f match = matchTemplate(L(T), L(I));


cv::rectangle(I, cv::Rect(match.x, match.y, T.cols, T.ro

cv::imshow("Template", T);
cv::imshow("Image", I);
cv::waitKey();

return 0;
}

P O S T E D BY HE LI O P E RR ON I F I L H O AT 1 0: 5 1 P M

Home Older Post

6/7 7.2.2017 22:25


Home Page of Helio Perroni Filho http://machineawakening.blogspot.com.tr/2015/12/fft-based-cosine-sim...

Subscribe to: Post Comments (Atom)

7/7 7.2.2017 22:25

You might also like