Understanding output from sitk.GetSpacing() - simpleitk

Can anyone explain me the meaning of the output that is generated from sitk.GetSpacing(). Also could anyone conform if I understood the concept of image spacing correctly, does it just mean the co-ordinate system for the image?

Yes, a spacing of [1,1,1] means that the pixels (voxels, really) are cubic, i.e., the same size in the X, Y, and Z dimensions.

Related

Find actual height of image from screen height with camera angle distortion

If my phone camera is at a known height on my phone and it takes a picture from a known distance, how can I find out the actual height of an object at the bottom of the picture, considering that the camera is taking the photo from a top angle?
This question talks of a similar problem, but the answers haven't taken camera angle and height into account.
Here's a diagram of the setup -
h is the actual height of the yellow box in front of the blue screen.
This is the image captured by the camera -
How can I find h, given h' on the image? Assume the focal length of the camera is known.
Assuming you know the calibration matrix K, here is a solution that I find simpler than calculating angles. Choose the points p1=(x,y) and p2=(r,s) as indicated in the figure above. Since you say that you know the distance from the camera to the object, that means you know the depth d of these points in camera coordinates, and
Q1=inverse(K)*p1*d
Q2=inverse(K)*p2*d
give you the corresponding points on the cube in camera coordinates. Now the height you seek is simply
abs(Q1-Q2)
Hope that helps.
Edit: Here's a quick explanation about the calibration matrix. When using the pinhole camera model, a 3d point P can be reprojected in the image plane via the multiplication KP where K is (assuming square pixels) the matrix
f 0 a
0 f b
0 0 1
where f is the focal length expressed in terms of pixel size, and [-a,-b]^t is the center of the image coorrdinates system (expressed in pixels). For more info, you can just goolge "intrinsic camera parameters", or for a quick and dirty explanation look here or here. And maybe my other answer can help?
Note: In your case since you only care about depth, you do not need a and b, you can set them to 0 and just set f.
PS: If you don't know f, you should look into camera calibration algorithms (there are auto-calibrating methods but as far as I know they require many frames and fall into the domain of SLAM/SFM). However, I think that you can find pre-computed intrinsic parameters in Blender for a few known smartphone models, but they are not expressed in the exact manner presented above, and you'll need to convert them. I'd calibrate.
I must be missing something, but I think this is quite easy (based on your assumptions, which include doing some type of image processing to detect the front and bottom edges of your object in order to get h') Keep in mind that you are also assuming that your distance from the top of the object to your camera is the same as from the bottom of your object to your camera. (at greater distances this becomes moot, but at close ranges, the skew can actually be quite significant)
The standard equation for distance:
dist = (focalDist(mm) * objectRealHeight(mm) * imageHeight(pix) ) / ( objectHeight(pix) * sensorHeight(mm) )
You can re-arrange this equation to solve for objectRealHeight since you know everything else...

Imrect doesn't get the correct size

I am showing an image so the user can select different ORI with the shape of rectangles always. My problem is that when I see the results of getPosition it gives me an x, y, width and height strange because if I use these numbers to extract this region I get another one totally different. Furthermore, they are too little to mark the current roi selected.
I think that the problem is because when I show the image Matlab reduces it to 67% because it says it is too big to show it so I think it's getting coordinates in a reduced image. Is there any way to get the real positions without this scale? I tried to divide these numbers by 0,67 but the result was not ok so I think matlab is not reducing the same in height than in width.
ok here is the crazy answer:
matlab x == y of your image
matbab y == x of your image
No matter with the scale.

Problems in implementing the integral image in MATLAB

I tried to implement the integral image in MATLAB by the following:
im = imread('image.jpg');
ii_im = cumsum(cumsum(double(im)')');
im is the original image and ii_im is the integral image.
The problem here is the value in ii_im flows out of the 0 to 255 range.
When using imshow(ii_im), I always get a very bright image which I am not sure is the correct result. Am I correct here?
You're implementing the integral image calculations right, but I don't understand why you would want to visualize it - especially since the sums will go beyond any normal integer range. This is expected as you are performing a summation of intensities bounded by larger and larger rectangular neighbourhoods as you move to the bottom right of the image. It is inevitable that you will get large numbers towards the bottom right. Also, you will obviously get a white image when trying to show this image because most of the values will go beyond 255, which is visualized as white.
If I can add something, one small optimization I have is to get rid of the transposing and use cumsum to specify the dimension you want to work on. Specifically, you can do this:
ii_im = cumsum(cumsum(double(im), 1), 2);
It doesn't matter what direction you specify first (2 then 1, or 1 then 2). The summation of all pixels within each bounded area, as long as you specify all directions to operate on, should be the same.
Back to your question for display, if you really, really, really really... I mean really want to, you can normalize the contrast by doing:
imshow(ii_im, []);
However, what you should expect is a gradient image which starts to be dark from the top, then becomes brighter when you get to the bottom right of the image. Remember, each point in the integral image calculates the total summation of pixel intensities bounded by the top left corner of the image to this point, thus forming a rectangle of intensities you need to sum over. Therefore, as we move further down and to the right of the integral image, the total summation should increase.
With the cameraman.tif image, this is the original image, as well as it's integral image visualized using the above command:
Either way, there is absolutely no reason why you would want to visualize it. You would use this directly with whatever application requires it (adaptive thresholding, Viola-Jones detector, etc.)
Another option could be applying a log operation for each value in the integral image. Something like:
imshow(log(1 + ii_im), []);
However, this will make most of the pixels have the same contrast and this is probably not useful. This is what I get with cameraman.tif:
The moral of this story is that you need some sort of contrast normalization so that you can fit all of the values in your integral image within the confines of the data type that is used to display the image on the screen using imshow.

what does MajorAxisLength property in regionprop matlab function mean?

I am using regionprop function in matlab to get MajorAxisLength of an image. I think logically this number should not be greater than sqrt(a^2+b^2) in wich a abd b are the width and heigth of the image. but for my image it is. My black and white image contains a black circle in the center of the image. I think this is strange. Can anybody help me?
Thanks.
If you look at the code of regionprops (subfunction ComputeEllipseParams), you see that they use the second moment to estimate the ellipsoid radius. This works very well for ellipsoid-shaped features, but not very well for features with holes. The second moment increases if you remove pixels from around the centroid (which is, btw, why they make I-beams). Thus, the bigger the 'hole' in the middle of your image, the bigger the apparent ellipsoid radius.
In your case, you may be better off using the extrema property of regionprops, and to calculate the largest radius from there.

matlab: correct approach to add geometrical objects to image

please help with Matlab beginner challenge
i need to create an image with few geometrical objects (circles,
ellipses) and then to apply some projective transforms
my problem is that i cant understand how to actually "draw" on image
image is AFAIU generally defined as [X;Y;3] matrix,
functions as SCIRCLE1 can compute/return collection of points
representing circle, but the problem is that points are not discrete ,
coordinates are real numbers and not pixels
how can i recompute the scircle output to be valid in image
coordinates system ? i.e. how can i "pixelize" it?
thanks for your attention, i really missing some basic concept and
will appreciate your help
John
well, below is an answer i received on Matlab newsgroups
BOTTOM LINE-no built-in way in Matlab
======================================
'getframe' can be used to merge axes even though it is more commonly used to create movie frames.
MATLAB is really weak in this area. There are some primitive
functions for drawing into the overlay (such as rectangle() if you
want to draw a circle, and line() if you want to draw a line) but no
real way that I know of to draw right into the underlying image. So
you have to use "tricks" such as getframe and then apply logical
operations. And you have to be careful with that since I think when
it gives you the rasterized version of the overlay it might be the
size of the image on the screen, not the true original matrix size of
the underlying image (I'd have to recheck this).
full thread here : http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/261232
I found this example which give you a easy way to put simple geometrical object onto pictures.
Read the input image.
I = imread('cameraman.tif');
Define the rectangle dimensions as [x y width height].
rectangle = int32([10 10 30 30]);
Draw the rectangle and display the result.
J = step(shapeInserter, I, rectangle);
imshow(J);
see this link
by the way..
I didn't get you point about points not being discrete and images being a matrix. The way I see it. It much the same. you could try to explain it more in depth ?
The insertShape function in the Computer Vision System Toolbox is what you need. It lets you draw rectangles, circles, and polygons into the image.
There is also insertText, insertMarker, and insertObjectAnnotation.