New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
recon image has shape (width+1,height+1) #34
Comments
Could you retry with an image that has width = odd integer? Either by cropping or padding the original image with zeroes. |
Hi Steve, thanks for pointing this out. As far as I understand, the current BASEX implementation only supports What I'm wondering about is there actually a physical reason why we can't generate basis sets for n=even? If so, we probably should ensure that the centering function produces the result of the shape ( |
Oh, this is weird, previously we would always produce an image that had an even size! We must have switched something when we were messing with the requirements for I don't see a conceptual reason why there should be any odd/even requirement for For computing the speeds, it makes the most sense not to have a "zero pixel", which we would have if We would be very happy to have the Hansen and Law iterative method incorporated into PyAbel. It seems to produce a bit less noise (especially centerline noise) than BASEX. Does it take a long time? I recall using one of Vrakking's iterative methods several years ago, and the results were good, but it took several minutes even for 1000x1000 pixels. I suppose downsampling the image to a smaller size could improve the speed... Either way, it would still be fun to experiment with! Having more methods to compare will just make things better. |
Oh, and thanks for pointing out that basex.exe cannot handle negative values. I did not realize this. We will need to point this out (along with the ability to use large images) if we write a "Features of PyAbel" section! :) One more thought about the 2048->2049 bug: It could just be the centering algorithm. If you have an even number image dimension, then it's not actually clear where the center should be. For example, if your image is 2 pixels wide, then the center is actually between pixel 0 and pixel 1. What happens if you set the center to be 1025 instead of 1024 as you are currently doing? |
Excellent, open source wins. The Hansen and Law algorithm core is ~13 lines of code. The inversion for a 2048x2048 pixel image takes 42 sec cf 16 sec for basex (for an already constructed basis), so about 1/2 the basex speed, but very usable. It is great to have other algorithms to use, and compare, which helps track down implementation faults, possibly centring in my case. Good comments about the definition of the image centre. While on this topic, My images are centred with respect to left cf right, and top cf bottom radial profiles, and are self-consistent with my own code (of course). For pyAbel I played with different centre offsets with the results that the spectral features broadened, so the image centre appears consistent with pyAbel. For even pixel number images, the centre is not a pixel, but the grid between pixels. It appears to be more complicated for odd pixel number images. |
Thanks for the details Steve. 42 seconds is not so bad for a huge image like that. The reduction in the centerline noise could be worth it depending on the situation. So yes, it would be great to incorporate it. The centering code actually lives in |
So, here is a minimal example that reproduces a problem with the centering function: import numpy as np
import matplotlib.pyplot as plt
import abel
data = np.zeros((5,5))
data[2,2]=1
fig = plt.figure(figsize=(12,6))
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
d2 = abel.tools.center_image(data,center=(2,2),n=5)
ax1.imshow(data,interpolation='nearest')
ax2.imshow(d2,interpolation='nearest')
ax1.set_title('Raw data')
ax2.set_title('Center=(2,2)')
plt.show() In the case of an image with an odd-size image, the center is clearly defined. But for an even-sized image, we need to make a formal decision if the center is at the left or right edge of the defined pixel. |
Hah, as an even-size image person, I tend to think that the even image centre is clearly defined, as the bottom left corner of the pixel (or the grid). This also facilitates the use of Python slicing functions. [May not be on topic] |
To add to the discussion, independently of the centering function, it looks like currently BASEX doesn't handle well even image sizes. For instance, here is a reconstruction of the Gaussian with Therefore, even if we agree on the way to fix the centering function (which we should at some point), the BASEX algorithm will produce incorrect results (and somebody would need to redo the math to understand why). Well, essentially this is only a problem when analyzing images (20x20), for e.g. 1024x1024 images, setting the center with +- 1 px precision should not matter (particularly as there is amplification of the noise on the axis), no? Can't we just keep the processing the way it is now (i.e. centering function that produces odd shapes, process with abel) and then simply remove one pixel row/column to get to the size of the original image? This way we would support both odd and even image, and although this is not ideal nor very clean, for all practical applications this shouldn't be an issue, don't you think? EDIT: sorry, yes as pointed by @stggh , for n odd the BASEX transform appears to be correct but shifted by 1/2 pixel on the right (I initially mistook the red curve with the blue one, intially). So either way of dealing with it should work. |
The even basex result appears to be correct, apart from the displacement off-centre. I agree that "for all practical applications this shouldn't be an issue". Definitely, allow basex processing of even images. |
@stggh, when you say that you define the center as the bottom left of the pixel, you have the origin at the bottom left, correct? So, the center is at the "lower index" side of the pixel in both the horizontal and vertical directions. This definition makes sense to me, so I would recommend that in the case of even images, we adopt the convention that the center is located at the low-index side of the defined pixel. This means that the defined center has different meanings in the case of odd and even sized images, but this seems unavoidable and as long as we document it, users should not get too confused. @rth, in the short run it looks like we should slide the even-sized image transform over a pixel in order to get it to line up. In the long run, we probably need to re-write the basex code for better readability and agreement with some sort of analytical math, either the Dribinski Rev. Sci. Instrum. paper or something that we write ourselves. We can put that off for a while. |
Now that I think about it more, the basex output for the even-sized image is not really correct. It contains a "central pixel", which an even-sized image should not. So, our basex algorithm only seems to make sense for an odd-sided image. I think that @rth is correct that the "quick fix" is to just make the original image odd-sized. In this case, it seems like the most honest thing to do would be to also return an odd sized image to the user. |
This is tricky. I would prefer that recon has the same size as the input image. Your plan for even images is to add one row and column AND shift the centre by 1/2 a pixel, then apply the basex inversion, returning an odd size image. I just want to check at the centre is also relocated? Tks. |
@DanHickstein would it make sense to eliminate the "first" basis function (k = 0 case, Fig 1, Dribinski et al paper) in the case of even functions? That way, there wouldn't be a need for a central pixel. |
Hmmmm, okay, maybe I need to go back and read the paper and figure out what's going on with the basis set generation. I think that you're correct that we need to eliminate the center basis function in the case of even sized images. I have some travel and other obligations for the next few days, so if one of you has time to think about this, that would be great. Otherwise I can work more about this later this week. |
@DanHickstein another possibility to think about is creating a "fake" column/row/both in even sized images (possibly by taking the average of the two columns/rows on either side of the "real" center), inserting it into the even We could then return the transform as-is to the user, or remove the added fake column/row/both and return a transform of the same size as |
@DhrubajyotiDas - the image centre would need to be also shifted = my query Edit: Opps! I miss interpreted your comment - explained by @rth approach #3 below. My apologies. |
So just to summarize the conversation above. Problem 1. I think we all agree on the definition of the center for an image as illustrated the @stggh comment. The centering function should be fixed properly in PR #38, #37. This can be done in Problem 2. The BASEX transform currently does not work with even image sizes.
I think that the image size should not be changed by the Basex transform. If we want a quick solution, I would rather go with the Approach 3., as interpolating on a new grid to shift by 1/2 pixel in Approach 2. would also have other undesired side effects (not sure what happens to noise etc). We could do this in v0.6. The clean solution would be Approach 4. which would require reading the paper in more detail. Personally, I won't be able to look into it this week. So maybe we can implement the Approach 3. which won't be very hard and finally release v0.6? Then we can work on fixing this problem more thoroughly under v0.7 with the Approach 4. ? |
Excellent summary and solution. I agree. The resulting speed data may also need correction? |
Today, on the call we arrived at the following conclusions about even vs odd images:
|
We have now implemented a |
PS: Great work guys!
The text was updated successfully, but these errors were encountered: