Creating a mask with 3 point in Matlab? - matlab

I have this 3 points (x,y) and I need to obtain a mask with a triangle where vertices is the points. I should respect some parameters, like the pixel pitch and I need a grid from the minimum x cordinate to the maximum x coordinate (the same for the y).
I tried to do this in matlab with the function poly2mask but the problem is the resultant image: when I have negative coordinates, I cannot see the polygon.
So I tried to center the polygon but I loose the original coordinates and I cannot have they back again because I need to do some elaboration on the image.
How I can obtain a mask triangle from 3 points without modifying the points and respecting the parameters?

Related

Find 3D coordinate with respect to the camera using 2D image coordinates

I need to calculate the X,Y coordinates in the world with respect to the camera using u,v coordinates in the 2D image. I am using an S7 edge camera to send a 720x480 video feed to MATLAB.
What I know: Z i.e the depth of the object from the camera, size of the camera pixels (1.4um), focal length (4.2mm)
Let's say the image point is at (u,v) = (400,400).
My approach is as follows:
Subtract the pixel value of center point (240,360) from the u,v pixel coordinates of the point in the image. This should give us the pixel coordinates with respect to the camera's optical axis (z axis). The origin is now at the center of the image. So new coordinates are: (160, -40)
Multiply the new u,v pixel values with pixel size to obtain the distance of the point from the origin in physical units. Let's call it (x,y). We get (x,y) = (0.224,-0.056) in mm units.
Use the formula X = xZ/f & Y = yZ/f to calculate X,Y coordinates in the real world with respect to the camera's optical axis.
Is my approach correct?
Your approach is going in the right way, but it would be easier if you use a more standardize approach. What we usually do is use Pinhole Camera Model to give you a transformation between the world coordinates [X, Y, Z] to the pixel [x, y]. Take a look in this guide which describes step-by-step the process of building your transformation.
Basically you have to define you Internal Camera Matrix to do the transformation:
fx and fy are your focal length scaled to use as pixel distance. You can calculate this with your FOV and the total pixel in each direction. Take a look here and here for more info.
u0 and v0 are the piercing point. Since our pixels are not centered in the [0, 0] these parameters represents a translation to the center of the image. (intersection of the optical axis with the image plane provided in pixel coordinates).
If you need, you can also add a the skew factor a, which you can use to correct shear effects of your camera. Then, the Internal Camera Matrix will be:
Since your depth is fixed, just fix your Z and continue the transformation without a problem.
Remember: If you want the inverse transformation (camera to world) just invert you Camera Matrix and be happy!
Matlab has also a very good guide for this transformation. Take a look.

Measure circularity or ellipticality

I have some binary images that want to classify them base on shape of them in MATLAB. If they have circular or elliptical shape they belong to class one,if they have elliptical shape with dent in their boundary they belong to class two. I dont know how can I use this feature. Can any body help me with this?
You can use the eccentricity property in regionprops. From MATLAB documentation of eccentricity:
The eccentricity is the ratio of the distance between the foci of the ellipse and its major axis length. The value is between 0 and 1. (0 and 1 are degenerate cases. An ellipse whose eccentricity is 0 is actually a circle, while an ellipse whose eccentricity is 1 is a line segment.)
So as the value of eccentricity increases , the ellipse starts becoming flatter. Hence, at its maximum value = 1, it is a line segment.
To check if there is a dent in the ellipse, you can use check for convexity. Whenever there is a dent in an ellipse, it will be non-convex. In other words, if you try to fit a convex polygon, it won't be able to approximate the shape well enough. You can use convexArea property to check the same. From MATLAB documentation of convexArea:
Returns a p-by-2 matrix that specifies the smallest convex polygon that can contain the region. Each row of the matrix contains the x- and y-coordinates of one vertex of the polygon. Only supported for 2-D label matrices.
So you use bwlabel to create a 2-D label matrix from your binary image and then check the difference between the area of your binary image and the area of the fitted convex polygon. Measuring area could be as simple as counting pixels. You already know that the number pixels of your fitted convex polygon = p. Just take the absolute difference between p and the number of pixels in your original binary image. You should be able to easily set a threshold to classify into one of the two classes.
I think you can write the code for this. Hope this helps.

Get coordinates of inlier points in Matlab

I need to find pixel values of inlier points obtained in object detection using impixel(). I am using the same code as provided in the example at the link
How can I get x,y coordinates of the inlier points being with respect to image dimensions.(Top-left corner of image considered as 0 row, 0 col) so that I can use the coordinates to find their respective pixel values. I couldn't find any solution in Matlab same as KeyPoint object in C++ that gives coordinate values easily.
You do not need impixel here. impixel lets you get the pixel value from in image displayed in a figure, which is not what you are trying to do.
In the example you are using, inlierBoxPoints and inlierScenePoints are SURFPoints objects. You can get the (x,y) locations of the points as inlierBoxPoints.Location. Then you can get the pixel value for the i-th point as follows:
loc = round(inlierBoxPoints.Location(i, :));
pixVal = boxImage(loc(2), loc(1), :);
Keep in mind that in MATLAB the images are indexed as (row, col), and that the top-left corner pixel is (1,1), not (0,0). You have to round off the coordinates, because the points are detected with sub-pixel accuracy.

Create depth map from 3d points

I have given 3d points of a scene or a subset of these points comprising one object of the scene. I would like to create a depth image from these points, that is the pixel value in the image encodes the distance of the corresponding 3d point to the camera.
I have found the following similar question
http://www.mathworks.in/matlabcentral/newsreader/view_thread/319097
however the answers there do not help me, since I want to use MATLAB. To get the image values is not difficult (e.g. simply compute the distance of each 3d point to the camera's origin), however I do not know how to figure out the corresponding locations in the 2d image.
I could only imagine that you project all 3d points on a plane and bin their positions on the plane in discrete, well, rectangles on the plane. Then you could average the depth value for each bin.
I could however imagine that the result of such a procedure would be a very pixelated image, not being very smooth.
How would you go about this problem?
Assuming you've corrected for camera tilt (a simple matrix multiplication if you know the angle), you can probably just follow this example
X = data(:,1);
Y = data(:,1);
Z = data(:,1);
%// This bit requires you to make some choices like the start X and Z, end X and Z and resolution (X and Z) of your desired depth map
[Xi, Zi] = meshgrid(X_start:X_res:X_end, Z_start:Z_res:Z_end);
depth_map = griddata(X,Z,Y,Xi,Zi)

Creating a cylinder with axis centered differently

I know Matlab has a function called cylinder to create the points for a cylinder when number of points along the circumference, and the radius length. What if I don't want a unit cylinder, and also don't want it to center at the default axis (for example along z-axis)? What would be the easiest approach to create such a cylinder? Thanks in advance.
The previous answer is fine, but you can get matlab to do more of the work for you (because the results of cylinder separate x,y,z components you need to work a little to do the matrix multiplication for the rotation). To have the center of base of the cylinder at [x0 y0 z0], scaled by [xf yf xf] (use xf=yf unless you want an elliptic cylinder), use:
[x y z] = cylinder;
h=mesh(x*xf+x0,y*yf+y0,z*zf+z0)
If you also want to rotate it so it isn't aligned along the z-axis, use rotate. For example, to rotate about the x-axis by 90 degrees, so it's aligned along the y-axis, use:
rotate(h,[1 0 0],90)
Multiply the points by your favourite combination of a scaling matrix, a translation matrix, and a rotation matrix.