Hi Malcolm,I currently have a PR for a normalized cross-correlation function (which was originally implemented by Pieter Holtzhausen). Comments/suggestions would definitely be appreciated.-Tony
Wow, those results are incredibly different. Yes, please put together a small script to reproduce the different behaviors (ideally, with the matlab result saved as .npy---or if it's easier .mat---file; also, if you can reproduce with a smaller image, that would be great).It'll be easy to check for switched arguments, but the rest might take some time for me to get to. In your original email, it sounded like you have some expertise in template matching; feel free to dig into the code and see if you can spot any errors in the code.Cheers,-Tony
I have used NCC a lot in my research, so I thought I'd take a look at this.
How critical is it that skimage's result image is the same size as
matlab's? The difference arises from the approach to the problem.
Matlab is assuming that the template might match an area of the target
image that isn't fully in frame. They probably pad the original image
(preferably with the target image average), and then do the cross
correlation on the padded image. This would explain the different
result size - Matlab seems to be M+m-1 by N+n-1. That means they pad
by the template width laterally, and the template height vertically.
They then have an M+2m x N+2n image, which they then apply the
template match to.
I haven't figured out the problem with the results not matching,
though. The "good" news is that the results with padding the matlab
way (pre-match) are especially fishy (nans are cropping up). That's
certainly an indicator of something rather fundamental being wrong.
I'm out of time for now, but I hope this helps a little. I will
investigate further when time allows, provided you all don't beat me
to it.
Best,
Mike
On Sat, Mar 24, 2012 at 2:16 PM, Mike Sarahan <msar...@gmail.com> wrote:
> I'm out of time for now, but I hope this helps a little. I will
> investigate further when time allows, provided you all don't beat me
> to it.
Thanks for looking into this, and for identifying the boundary issue.
The fact that there are differences even with padding is
disconcerting; I'll see if I can review this soon.
Stéfan
Glad you figured this out.
I'm also not a huge fan of the Matlab-style padding. I guess
theoretically, it gives your match greater range - beyond the bounds
of the image. In practice, I found that such behavior in the presence
of noise often gave me a peak outside the image, when I knew I wanted
my peak inside the image.
I'm mixed on the input padding. Intuitively, I think the high value
at template center is easier to understand for a human looking at the
cross correlation result image. I know that this confused me a lot
when I first encountered cross correlation using OpenCV. However, any
subsequent analysis (peak finding, for example) would have to account
for the difference, and I think this would be more of a headache than
a benefit to people. I can imagine a lot of careless analyses with
offsets of exactly half the template dimensions.
Your proposed method for the padding makes more sense to me than
Matlab's. I would recommend defaulting to no padding, and also
recommend a little documentation that warns the user about the offset
they will have to account for if using the pad option.
I can't think of a use case for padding the output with zeros. If
anyone else knows one, I'll be happy to learn, though.
Best,
Mike
Hi Tony,
Glad you figured this out.
I'm also not a huge fan of the Matlab-style padding. I guess
theoretically, it gives your match greater range - beyond the bounds
of the image. In practice, I found that such behavior in the presence
of noise often gave me a peak outside the image, when I knew I wanted
my peak inside the image.
I'm mixed on the input padding. Intuitively, I think the high value
at template center is easier to understand for a human looking at the
cross correlation result image. I know that this confused me a lot
when I first encountered cross correlation using OpenCV. However, any
subsequent analysis (peak finding, for example) would have to account
for the difference, and I think this would be more of a headache than
a benefit to people. I can imagine a lot of careless analyses with
offsets of exactly half the template dimensions.
Your proposed method for the padding makes more sense to me than
Matlab's. I would recommend defaulting to no padding, and also
recommend a little documentation that warns the user about the offset
they will have to account for if using the pad option.
I can't think of a use case for padding the output with zeros. If
anyone else knows one, I'll be happy to learn, though.
Best,
Mike
Just as a point of interest, there should soon be some padding
capabilities in numpy:
https://github.com/numpy/numpy/pull/198
Stéfan
On Sat, Mar 24, 2012 at 4:03 PM, Tony Yu <tsy...@gmail.com> wrote:
> zero, but round-off errors are causing it to go negative. If that's the
> case, then it's an easy fix to check that the argument is positive, but
> someone should check my math to make sure the the code matches the equation.
I checked the paper vs your code, and the code looks correct. The
only thing I didn't check was whether the normalization was done on
the correct position in the correlation.
> Padding *the input* sounds like a good idea, but I think it should be done
> in such a way that the output is (M, N)---i.e. same size as the input image.
> I'm not a huge fan of the Matlab output size (but maybe some people expect
> this output?).
If the user wants to pad the input, they should probably do that
themselves beforehand. Half-template matches feel sketchy (and where
do you stop: when at least half the template matches?). Also, with
the new proposed padding in numpy, this should become a lot easier.
Stéfan
Hi Tony
I checked the paper vs your code, and the code looks correct. The
On Sat, Mar 24, 2012 at 4:03 PM, Tony Yu <tsy...@gmail.com> wrote:
> zero, but round-off errors are causing it to go negative. If that's the
> case, then it's an easy fix to check that the argument is positive, but
> someone should check my math to make sure the the code matches the equation.
only thing I didn't check was whether the normalization was done on
the correct position in the correlation.
If the user wants to pad the input, they should probably do that
> Padding *the input* sounds like a good idea, but I think it should be done
> in such a way that the output is (M, N)---i.e. same size as the input image.
> I'm not a huge fan of the Matlab output size (but maybe some people expect
> this output?).
themselves beforehand. Half-template matches feel sketchy (and where
do you stop: when at least half the template matches?). Also, with
the new proposed padding in numpy, this should become a lot easier.
Stéfan
It looked like you took the result of np.correlate, and then
normalized those coefficients. I wasn't sure (didn't verify) whether
the normalization was computed for the correct position in the
np.correlate result.
> Hmm, I was under the impression that half-template matches would be
> appropriately penalized.
That explanation seems reasonable--such behaviour seems totally sane.
Stéfan
On Mon, Mar 26, 2012 at 6:36 PM, Tony Yu <tsy...@gmail.com> wrote:It looked like you took the result of np.correlate, and then
> Thanks for checking. What do you mean by "correct position in the
> correlation"?
normalized those coefficients. I wasn't sure (didn't verify) whether
the normalization was computed for the correct position in the
np.correlate result.
That explanation seems reasonable--such behaviour seems totally sane.
> Hmm, I was under the impression that half-template matches would be
> appropriately penalized.
Stéfan