Is there a concave-hull algorithm where points to be excluded can be specifed? - concave-hull

So I have a list of points (2d) that should be inside a polygon, and a second list of points that should be outside the polygon. I want to find the polygon that encloses the "inside" points while excluding the "outside" points.
The resulting polygon will almost certainly be concave. I would like to minimise the number of edges it has, but any other sensible criteria would probably do. It seems likely that some approach that started with the convex hull, and then took chunks out of it would work.
I am wondering if this could be achieved using alpha shapes, while varying alpha. There is already a nice python implementation for that; https://pypi.org/project/alphashape/
but I haven't worked out exactly how I'd need to vary alpha.

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...

how to perform hough transformfor finding hand curve

hi i want to detect fingertips point and valleypoint of hand by using hough transform.Simply the Question is what is the [H,theta,rho]=hough(BW) is good for extract these point.
the image is here:
https://www.dropbox.com/sh/n1lz7b5eedzbui7/AADwy5O1l7sWf5aOx7KWAmhOa?dl=0
tnx
The standard hough transformation is just for detecting straight lines. Not more and not less. The Matlab function hough (please see here) returns the so-called hough space H, a parametric space which is used to find these lines and the parametric representation of each line: rho = x*cos(theta) + y*sin(theta).
You will have to do more than this to detect your desired points. Since your fingers usually won't consist of straight lines, I think you should think of something else anyway, e.g. if you can assume such a perfect curve as the one in your image maybe this is interesting for you.
Another simple technique you might consider is to compare the straight line distance between two points on your hand line to the distance between those two points along the perimeter (geodesic distance). For this you would need an ordered list of points along the perimeter.
Along regions of high curvature, the straight line distance between two points will be smaller than the number of pixels between those two points along the perimeter.
For example, you could check perimeter pixels separate by 10 pixels. That is, you would search through the list and compare the point at index N and the point index N+10. (You'll need to loop back around to the beginning of the list as you approach the end.) If the straight line distance between these two points is nearly 10 pixels as well, then you know those points lie on a straight section of the perimeter. If the straight line distance is much smaller than 10, then you know the perimeter curves in some fashion between those points. Whether you check pixels that are 5, 10, 20, or 30 items apart in the list will depend on the resolution of your image and the curves you're looking for.
This technique is useful because it's simple and quick to implement. Maybe it would work well enough for your needs.
Yet another way: simplify the outline to small line segments, and then you can calculate the line-line angle between adjacent segments. To simplify the curves, implement the Ramer-Douglas-Puecker algorithm. A little experimentation will reveal what parameter settings will work for your application.
https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
Finally, you could look into piecewise curve fitting: a curve would be fitted to small segments of the outline. This can get very complicated, and researchers continue to find ways to decompose complex figures into a limited number of more basic shapes or curves. I recommend trying the simplest technique and then only adding complexity if you need it.

How can I interpolate points in 3D space?

I have 3D space. And I know for example N points in this space (x1,y1,z1), (x2,y2,z2)..., (xn,yn,zn). I want to interplolate points, that is different from this. How can I do this in Matlab?
interp3 may help you. Here is the documentation.
As always, there are questions left unanswered by your one line query.
If the data is of the form where there is a functional relationship z(x,y), (or y(x,z) or x(y,z)) then you might potentially be able to use one of the interpolation tools. Thus, suppose you have data that lies on a lattice in the (x,y) plane, thus some value of z at each point in that lattice. In this case, you can use interp2.
Alternatively, if the data is scattered, but there is some single valued functional relationship z(x,y) that you don't have, but it is some continuous function. Infinite first derivatives are a problem too here. In this case, assuming that you have data that at least fills some convex domain in the (x,y) plane, you can still interpolate a value of z. For this, use griddata, or TriScatteredInterp. Or you might use my own gridfit tool, as found on the file exchange.
Next, the way you describe the data, I'm not at all positive that you have something in one of the above forms. For example, if your data lies along some curved path in this 3D domain, and you wish to interpolate points along that curved arc can be done using my interparc tool, also found on the file exchange.
One last case that people often seem to have when they talk about interpolation of a spatial set like this, is just a general surface, that they wish to build a neatly interpolated, smooth surface. It might be something as simple as the surface of a sphere, or something wildly more complex. (These things are never simple.) For this, you might be able to use a convex hull to approximate something, if it is a closed convex surface. More complex surfaces might require a tool like CRUST, although I have no implementation of it I can offer to you. Google will help you there, if that is what you need.
The point of all this is, how you interpolate your data depends on what form the data is in, what it represents, and the shape of the relationship you will be interpolating.

Segmenting 3D shapes out of thick "lines"

I am looking for a method that looks for shapes in 3D image in matlab. I don't have a real 3D sample image right now; in fact, my 3D image is actually a set of quantized 2D images.
The figure below is what I am trying to accomplish:
Although the example figure above is a 2D image, please understand that I am trying to do this in 3D. The input shape has these "tentacles", and I have to look for irregular shapes among them. The size of the tentacle from one point to another can change around but at "consistent and smooth" pace - that is it can be big at first, then gradually smaller later. But if suddenly, the shape just gets bigger not so gradually, like the red bottom right area in the figure above, then this is one of the volume of interests. Note that these shapes have more tendency to be rounded and spherical, but some of them are completely arbitrary and random.
I've tried the following methods so far:
Erode n times and dilate n times: given that the "tentacles" are always smaller than the volume of interest, this method will work as long as the volume is not too small. And, we need to have a mechanism to deal with thicker portion of the tentacle that becomes false positive somehow.
Hough Transform: although I have been suggested this method earlier (from Segmenting circle-like shapes out of Binary Image), I see that it works for some of the more rounded shape cases, but at the same time, more difficult cases such that of less-rounded, distorted, and/or arbitrary shapes can slip through this method.
Isosurface: because of my input is a set of 2D quantized images, using an isosurface allow me to reconstruct image in 3D and see things clearer. However, I'm not sure what could be done further in this case.
So can anyone suggests some other techniques for segmenting such shape out of these "tentacles"?
Every point on your image has the property that it is either part of the tentacle, or part of the volume of interest. If it is unknown apriori what the expected girth of the tentacle is, then 1 wont work because we won't be able to set n. However, we know that the n that erases the tentacle is smaller than the n that erases the node. You can for each point replace it with an integer representing the distance to the edge. Effectively, this can be done via successive single pixel erosion, and replacing each pixel with the count of the iteration at which it was erased. Lets call this the thickness at the pixel, but my rusty old mind tells me that there was a term of art for this.
Now we want to search for regions that have a higher-than-typical morphological distance from the boundary. I would do this by first skeletonizing the image (http://www.mathworks.com/help/toolbox/images/ref/bwmorph.html) and then searching for local maxima of the thickness along the skeleton. These are points on the skeleton where the thickness is larger than the neighbor points.
Finally I would sort the local maxima by the thickness, a threshold on which should help to separate the volumes of interest from the false positives.

Fast way to convert array of points into triangle strip?

I have an array of CGPoints (basic struct with two floats: x and y). I want to use OpenGL ES to draw a textured curve using these points. I can do this fine with just two points, but it gets harder when I need to make a line from several points.
Currently I draw a line horizontally, calculate its angle from the points given, and then rotate it. I don't think doing this for all lines in a curve is a good idea. There's probably a faster way.
I'm thinking that I can "enlarge" or "constrict" all the points at once to make a curve with some sort of width.
I'm not positive what you want to accomplish, but consider this:
Based on a ordered list of points, you can draw a polyline using those points. If you want to have a polyline with a 2D texture on it, you can draw a series of quadrilaterals (using two triangles each, of course). You can generate these quadrilaterals using an idea similar to catmul-rom spline generation.
Consider a series of points p[i-1], p[i], p[i+1]. Now, for each i, you can find two points each an epsilon distance away from p[i] along the line perpendicular to the line connecting p[i-1] and p[i+1]. You can determine the two points generated for the endpoints in various ways, like using the perpendicular to the line from p[0] to p[1].
I'm not sure if this will be faster than your method, but you should be caching the results. If you are planning on doing this every frame, another type of solution to your problem may be needed.