Finding the concavness pixel/point in binary map using Matlab - matlab

Given an binary mask with an object in Matlab. I am going to find the concavity point of the object boundary. The concavity point I mean here is the deepest concavity point with respect to the Euclidean distance to the convex hull chords K_1, K_2 ,and K_3 in the concavity regions B_1, B_2, B_3, respectively. The red dot indicates the concavity point I want to find, where in concavity region B_1 I draw three lines perpendicular to the chord K_1, the deepest concavity point is the middle one since it has the largest length.
Anyone have efficient way/code to do that? Thanks.
Another figure below gives an example with the convex hull, where the red dot indicates the valid concavity point.

Efficient is relative...
How about computing the convex hull (there are standard algorithms for it) and then shrinking it until it is completely inside the object boundaries. The last point touching is your desired concavity point.
Alternative strategy:
calculate convex hull
find all differences between convex hull and object boundary (have to be straight lines, K1 K2 K3 in your case)
for every line, rotate image such that line is horizontal
take the lowest pixel of the object boundary below the line

Related

How to check if given 3d point is outside convex hull

I'm working on a science project. I have a list of xyz-coordinates of voronoi diagram vertices, and a list of points that create my protein's convex-hull (from triangulation). Now some of the vertices lie quite far from the hull and I'd like to filter them out. How can I do it in c++ ? For now it doesn't have to be super optimised, I'm only focused on removing those points.
visualization
I was also thinking to check if a line from voronoi vertex(red crosses) to center of protein(pink sphere) is intersecting with hull face at any point, but I'm not sure how to achive that.
I've read that you can check if a point is inside a polygon by counting the times an infinite line from the point is crossing the hull, but that was for two dimensions. Can similar approach be implemented to suit my needs ?
https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
Let's start with the two-dimensional case. You can find the solution to that on CS.SX:
Determine whether a point lies in a convex hull of points in O(logn)
The idea is that each two consecutive points on the convex hull define a triangular slice of the plane (to some internal point of the hull); you can find the slice in which your point is located, and check whether it's closer to the internal point than the line segment bounding the slide.
For the three-dimensional case, I'm guessing you should be able to do something similar, but the search for the 3 points forming the relevant triangle might be a little tricky. In particular, it would also depend on how the convex hull is represented - as in the 2-d case the convex hull is just a sequence of consecutive points on a cycle.
I know this doesn't quite solve your problem but it's the best I've got given what you've written...

Convex Hull with a predefined number of vertices

I am working on image segmentation and I thought the convex hull can provide me with a simple solution to my problem. Currently I have polygons with for sides (see image below). Due to image processing issues, the shape does not have clean straight sides and hence when I use the standard convex hull (in Matlab) I may get more than the four main corners to define it.
My goal is to force the convex hull algorithm to find the best 4 vertices that will enclose my polygons (i.e. 4 best enclosing vertices per polygon). Is this possible? An example code will be appreciated.
Thanks
The problem of the minimum area bounding polygon is briefly mentioned in "Geometric applications of a matrix-searching algorithm" (see Applications section). It is not simple and is probably not the way for you.
For an easier (but approximate) answer to your question, you can consider the four cardinal directions and find the farthest points in these, which define a quadrilateral. (Also consider the four intermediate directions, which are more appropriate for an axis-aligned rectangle.)
If you insist having an enclosing quadrilateral, you can translate the four edges to the farthest points in the respective perpendicular directions, and find the pairwise intersections.
If you insist having a rectangle, compute the convex hull and find the minimum area or minimum perimeter bounding rectangle by the Rotating Calipers method. https://geidav.wordpress.com/tag/rotating-calipers/

Identifying concave hull of points in higher dimension

I have a set of points(clusters) in higher dimension (30d to 100d). I need to identify concave hull of these points in an efficient manner.
Is there a way to do get the exact concave hull or atleast approximate concave hull of these set of points?
Further, if we have a set of points identified as a border point, is there a way to verify whether the points are actually border points?
In 100d, almost every point will be on the convex hull.
Just remember that a rectangle in 2d has 4 corners, but in 100d, it has 2^100 corners.
As an extremely rough approximation, take the minimum and maximum along each axis. If it is unique, the point is on the hull. For additional points, you can sample some random projections.
But again, the expected behaviour is that almost every point is on the hull, because it is the smallest or largest in some linear combination of features.

Arrange the vertices of a 3D convex polygonal plane in counter clockwise direction in MATLAB

I have a convex polygon in 3D. For simplicity, let it be a square with vertices, (0,0,0),(1,1,0),(1,1,1),(0,0,1).. I need to arrange these vertices in counter clockwise order. I found a solution here. It is suggested to determine the angle at the center of the polygon and sort them. I am not clear how is that going to work. Does anyone have a solution? I need a solution which is robust and even works when the vertices get very close.
A sample MATLAB code would be much appreciated!
This is actually quite a tedious problem so instead of actually doing it I am just going to explain how I would do it. First find the equation of the plane (you only need to use 3 points for this) and then find your rotation matrix. Then find your vectors in your new rotated space. After that is all said and done find which quadrant your point is in and if n > 1 in a particular quadrant then you must find the angle of each point (theta = arctan(y/x)). Then simply sort each quadrant by their angle (arguably you can just do separation by pi instead of quadrants (sort the points into when the y-component (post-rotation) is greater than zero).
Sorry I don't have time to actually test this but give it a go and feel free to post your code and I can help debug it if you like.
Luckily you have a convex polygon, so you can use the angle trick: find a point in the interior (e.g., find the midpoint of two non-adjacent points), and draw vectors to all the vertices. Choose one vector as a base, calculate the angles to the other vectors and order them. You can calculate the angles using the dot product: A · B = A B cos θ = |A||B| cos θ.
Below are the steps I followed.
The 3D planar polygon can be rotated to 2D plane using the known formulas. Use the one under the section Rotation matrix from axis and angle.
Then as indicated by #Glenn, an internal points needs to be calculated to find the angles. I take that internal point as the mean of the vertex locations.
Using the x-axis as the reference axis, the angle, on a 0 to 2pi scale, for each vertex can be calculated using atan2 function as explained here.
The non-negative angle measured counterclockwise from vector a to vector b, in the range [0,2pi], if a = [x1,y1] and b = [x2,y2], is given by:
angle = mod(atan2(y2-y1,x2-x1),2*pi);
Finally, sort the angles, [~,XI] = sort(angle);.
It's a long time since I used this, so I might be wrong, but I believe the command convhull does what you need - it returns the convex hull of a set of points (which, since you say your points are a convex set, should be the set of points themselves), arranged in counter-clockwise order.
Note that MathWorks recently delivered a new class DelaunayTri which is intended to superseded the functionality of convhull and other older computational geometry stuff. I believe it's more accurate, especially when the points get very close together. However I haven't tried it.
Hope that helps!
So here's another answer if you want to use convhull. Easily project your polygon into an axes plane by setting one coordinate zero. For example, in (0,0,0),(1,1,0),(1,1,1),(0,0,1) set y=0 to get (0,0),(1,0),(1,1),(0,1). Now your problem is 2D.
You might have to do some work to pick the right coordinate if your polygon's plane is orthogonal to some axis, if it is, pick that axis. The criterion is to make sure that your projected points don't end up on a line.

How to find ALL points that lie on the outline of a polygon's convex hull (Matlab)

sorry if this question might seem simple but I couldn't figure it out.
Imagine two arbitrary Rectangles that are randomly overlaped so that their outlines intersect at only two locations. Now you cut the area of overlap out of Rectangle 1.
This "bitten Rectangle 1" has now the following points (vertices): (1) All points of Rectangle 1 that lie outside of Rectangle 2, (2) All points of Rectangle 2 that lie inside Rectangle 1 and (3) the two intersection points.
The problem know is the following: How can I get the order of the new points so that the functions plot(...) or fill(...) would draw the right "Bitten Rectangle 1"?
What I did so far:
I determined the convex hull of all the points that lie outside of Rectangle 2 + the intersection points. Then one has to add the new points that lie inside rectangle 1 (due to overlap with Rectangle 2) between the indices of the first and second intersection point also in the right order.
The problem with this convex hull approach is that it only works if the intersection points lie on different lines of Rectangle 1, because then they are part of the convex hull.
If they lie on the same line they are no longer treated as part of the convex hull.
What I'd need is a method to get the order of all possible points that lie on the convex hull and not only the outer most ones.
Hope anybody can help me...
Thank you in advance,
Patrick
In Matlab, there is an amazing function called polybool that let you do any set operation on polygons: http://www.mathworks.com/help/toolbox/map/ref/polybool.html
All you have to do is to define four arrays describing the rectangles (rect1x, rect1y, rect2x and rect2y) and to call [resultx resulty] = polybool('subtraction', rect1x, rect1y, rect2x, rect2y). The resulting arrays will be describing the "Bitten Rectangle 1".