I have two equally-sized data-arrays (mainly zeros, and sparsely filled with ones), and make the conv of it. As a result I get this.
Now one can see a peak around -10^{-5}. My question is, how can I do the convolution such that I only get a small region around that peak?
I know that the convolution is defined from minus infinity to infinity. Mathematically I would want to change those limits to (in my example) [-1.5*10^5,-0.5*10^-5].
Thanks alot for your help!
edit
I found the solution: One can use xcorr(a,fliplr(b)) instead of conv(a,b). Now xcorr has the option "maxlags", which is exactly the thing I was searching for.
You can reduce the number of output values of conv, but not arbitrarily. Try 'same' or 'valid' options:
C = CONV(A, B, SHAPE) returns a subsection of the convolution with size specified by SHAPE:
'full' - (default) returns the full convolution,
'same' - returns the central part of the convolution
that is the same size as A.
'valid' - returns only those parts of the convolution
that are computed without the zero-padded edges.
LENGTH(C)is MAX(LENGTH(A)-MAX(0,LENGTH(B)-1),0).
To specify arbitrary output limits, you probably need to do the convolution manually with a user-defined function. But it may be more efficient to use conv and then trim the output.
Related
There are multiple ways to do sharpening on image using matlab
for example
im=imsharpen(old_image,'Radius',2,'Amount',1);
im=imfilter(old_image,fspecial('unsharp'));
imshow(im)
how can i undo this operation(sharpening) and return the original image??
You cannot undo the effect of a filter, in general. Filtering, even sharpening filters, combines the values in a neighborhood, reducing information.
For a small class of linear filters, those that do not zero out any frequencies, it is possible to reverse the operation to a certain extent. This requires that no clipping occurred. That is, the result of the filter was saved as floating-point values rather than uint8 or similar. Reversing the operation then involves multiplying in the frequency domain by the point-wise inverse of the filter. The linear filter kernel h convolves the image f, that implies that they are multiplied in the frequency domain, roughly: g = ifftn(fftn(f).*fftn(h)). Then f = ifftn(fftn(g)./fftn(h)).
I say roughly because the above requires padding h to the size of f.
Note that where fftn(h) is 0, the division results in NaN (since you do 0/0), not the original value of f. This puts a strong limit to the class of filters that you can "undo". Furthermore, if the filtered image has noise added (this is likely except for purely theoretical cases) then the noise will be amplified for frequencies where the filter has small values. Basically, even small amounts of noise make this process fail.
The Wiener filter does the above with regularización, such that noise and near-zero filter values don't cause to blow out your answer. There are more complex iterative solvers for the ill-posed inverse transform, but that is a large topic. Start your search with Wiener and you'll eventually discover those too.
On the other hand, if you are looking for a filter that does the opposite --smoothing -- look for example for imgaussfilt.
Due to the nature of my problem, I want to evaluate the numerical implementations of the Radon transform in Matlab (i.e. different interpolation methods give different numerical values).
while trying to code my own Radon, and compare it to Matlab's output, I found out that my radon projection sizes are different than Matlab's.
So a bit of intuition of how I compute the amount if radon samples needed. Let's do the 2D case.
The idea is that the maximum size would be when the diagonal (in a rectangular shape at least) part is proyected in the radon transform, so diago=sqrt(size(I,1),size(I,2)). As we dont wan nothing out, n_r=ceil(diago). n_r should be the amount of discrete samples of the radon transform should be to ensure no data is left out.
I noticed that Matlab's radon output is always even, which makes sense as you would want a "ray" through the rotation center always. And I noticed that there are 2 zeros in the endpoints of the array in all cases.
So in that case, n_r=ceil(diago)+mod(ceil(diago)+1,2)+2;
However, it seems that I get small discrepancies with Matlab.
A MWE:
% Try: 255,256
pixels=256;
I=phantom('Modified Shepp-Logan',pixels);
rd=radon(I,pi/4);
size(rd,1)
s=size(I);
diagsize=sqrt(sum(s.^2));
n_r=ceil(diagsize)+mod(ceil(diagsize)+1,2)+2
rd=
367
n_r =
365
As Matlab's Radon transform is a function I can not look into, I wonder why could it be this discrepancy.
I took another look at the problem and I believe this is actually the right answer. From the "hidden documentation" of radon.m (type in edit radon.m and scroll to the bottom)
Grandfathered syntax
R = RADON(I,THETA,N) returns a Radon transform with the
projection computed at N points. R has N rows. If you do not
specify N, the number of points the projection is computed at
is:
2*ceil(norm(size(I)-floor((size(I)-1)/2)-1))+3
This number is sufficient to compute the projection at unit
intervals, even along the diagonal.
I did not try to rederive this formula, but I think this is what you're looking for.
This is a fairly specialized question, so I'll offer up an idea without being completely sure it is the answer to your specific question (normally I would pass and let someone else answer, but I'm not sure how many readers of stackoverflow have studied radon). I think what you might be overlooking is the floor function in the documentation for the radon function call. From the doc:
The radial coordinates returned in xp are the values along the x'-axis, which is
oriented at theta degrees counterclockwise from the x-axis. The origin of both
axes is the center pixel of the image, which is defined as
floor((size(I)+1)/2)
For example, in a 20-by-30 image, the center pixel is (10,15).
This gives different behavior for odd- or even-sized problems that you pass in. Hence, in your example ("Try: 255, 256"), you would need a different case for odd versus even, and this might involve (in effect) padding with a row and column of zeros.
Can someone explain to me the correlation function corr2 in MATLAB? I know that it is for 2D comparing similarities of objects, but in the equation I have doubts what it is A and B (probably matrices for comparison), and also Amn and Bmn.
I'm not sure how MATLAB executes this function, because I have found in several cases that the correlation is not executed for the entire image (matrix) but instead it divides the image into blocks and then compares blocks of one picture with blocks of another picture.
In MATLAB's documentation, the corr2 equation is not put as referral point to the way the equation itself is calculated, like in other functions in MATLAB's documentation, such as referring to what book it is taken from and where it is explained.
The correlation coefficient is a number representing the similarity between 2 images in relation with their respective pixel intensity.
As you pointed out this function is used to calculate this coefficient:
Here A and B are the images you are comparing, whereas the subscript indices m and n refer to the pixel location in the image. Basically what Matab does is to compute, for every pixel location in both images, the difference between the intensity value at that pixel and the mean intensity of the whole image, denoted as a letter with a straightline over it.
As Kostya pointed out, typing edit corr2 in the command window will show you the code used by Matlab to compute the correlation coefficient. The formula is basically this:
a = a - mean2(a);
b = b - mean2(b);
r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b)));
where:
a is the input image and b is the image you wish to compare to a.
If we break down the formula, we see that a - mean2(a) and b-mean2(b) are the elements in the numerator of the above equation. mean2(a) is equivalent to mean(mean(a)) or mean(a(:)), that is the mean intensity of the whole image. This is only calculated once.
The 3rd line of code calculates the coefficient. Here sum(sum(a.*b)) calculates the double-sum present in the formula element-wise, that is considering each pixel location separately. Be aware that using sum(a) calculates the sum in every column individually, hence in order to get a single value you need to apply sum twice.
That's pretty much the same happening in the denominator, however calculations are performed on a-mean2(a)^2 and b-mean2(b)^2. You can see this a some kind of normalization process in which you consider the pixel intensity difference among each individual image.
As for your last comment, you can break down an image into small blocks and calculate the correlation coefficient on them; that might save some time for very large images but since everything is vectorized the calculation is quite fast. It might be useful in distributed processing I guess. Of course the correlation coefficient between 2 blocks of images is not necessarily identical to that of the whole image.
For the sake of curiosity you can look at this paper which highlights some caveats in using the correlation coefficient for image comparison.
Hope that makes things a bit clearer!
I have been using Matlab's normxcorr2 function to do template matching with images by performing normalized cross correlation. To find the maximum correspondence between a template and an image, one can simply run normxcorr2 and then find the maximum absolute value of all the values returned by normxcorr2 (the function returns values between -1.0 and 1.0).
From a quick Google search, I found out that a negative correlation coefficient means an inverse relationship between two variables (e.g. as x increases, y decreases), and that a positive correlation coefficient means the opposite (e.g. as x increases, y increases). How does this apply to image template matching? That is, what does a negative value from normxcorr2 mean conceptually with respect to template matching?
View normalized cross correlation as a normalized vector dot product. If the angle between two vectors is zero, their dot product will be 1; if they are facing in the opposite direction, then their dot product with be negative 1. This is idea is actually direct if you take the array and stack the column end to end. The result is essentially a dot product between two vectors.
Also just as a personal anecdote: what confused me about template matching at first, was intuitively I believed element wise subtraction of two images would be a good metric for image similarity. When I first saw cross correlation, I wondered why it used element wise multiplication. Then I realized that the later operation is the same thing as a vector dot product. The vector dot product, as I mentioned before, indicates when two vectors are pointing in the same direction. In your case, the two vectors are normalized first; hence why the range is from -1 to 1. If you want to read more about the implementation, "Fast Normalized Cross Correlation" by J.P. Lewis is a classical paper on the subject.
Check the formula
on wikipedia.
When f(x, y) - mean(f) and t(x,y) - mean(t) have different sign the result of an addendum will be negative (std is always positive). If there are a lot of such (x,y) then the whole sum will also be negative. You may think that if 1.0 means that one image is equal to another. -1.0 means that one image is a negative of another (try to find normxcorr2(x, -x))
According to MATLAB's documentation the $p$-th bin contains the pixels between
$A\frac{(p-1.5)}{n-1}\leq x<A\frac{p-0.5}{n-1}$, where $x$ is the pixel intensity, and $n$ is the number of bins.
As far as I can understand this, $A$ is a scaling factor that is the maximal value of the data type used (e.g. if $A=1$ we consider an image with $x\in[0,1]$).
What I don't really understand, why we use the constants in the expression; for the first bin (assuming that MATLAB considers $p=1$ instead of $p=0$ as the first bin) we put values between $x\in[\frac{-0.5}{(n-1)}, \frac{0.5}{(n-1)}]$, but we have values between $x\in[0,1]$ so the effective width of the bin is only half of the "normal" bins (same goes to the last bin). Why don't MATLAB use $A\frac{p}{n-1}\leq x<A\frac{p+1}{n-1}$ for $p\in[0,n-1]$?
The answer was actually pretty easy and not MATLAB-related: if you divide your domain equidistantly (and choose these values as the representative value of the corresponding quantization level) and pick thresholds at the centroid of each of these intervals endpoints you get the thresholds that MATLAB uses.