Volume overlap of two convex hulls - python

I have two sets of points which I can transform into a 3D convex hull via skimage's convex hull function. Is there some computationally efficient way with which to determine the overlap volume of the two 3D hulls formed this way?
Thanks

Borrowing insights from the comments:
First, I think you are interested in the intersection mesh, not the union. Once you have the vertices for the intersection mesh, I believe you can simply calculate the convex hull volume of that mesh using scipy.spatial.ConvexHull.

Related

How to calculate the shape from lon/lat coordinates and draw it with plotly

I have a plotly based map where I am showing several coordinates in a Mapbox scatter plot. Now I want to get a shape from these coordinates and draw a shape on the map.
The coordinates are available as a pandas.Series. Below an extract of the coordinates.
0 [[51.795, 3.363], [51.79483333333334, 3.363], ...
1 [[51.42536, 2.622246666666667], [51.4256883333 ...
How can I get a shape for these coordinates which boundaries are the outmost coordinates of the cluster?
In geometry, there are basically two main concepts Convex hull and Alpha shape (also called Concave hull) to get the shape of a finite set of points. The following picture should visually describe the differences between them [2].
In case you want to have the convex hull you can use scipy.spatial.ConvexHull [4].
As alternatives to scipy you can also check geopandas and alphashape.

Open CV Contours - Splitting concave polygon into multiple convex ones

I have the below image in a numpy array
I want to
separate the blocks into individual contours or any coordinate representation.
I then want to transform any concave polygons into multiple convex polygons.
Like this
So far I've managed to isolate each block into contours with opencv... but is there an easy way to split the L shape objects into two or more square blocks. The new contours of each shape can overlap if needed.
It may also be the case that I have an Image like this which does not have such straight lines.
I have used cv2.approxPolyDP to draw the shape, but again they are concave and I need them splitting.
Any help appreciated.
One way I can think of is, for each contour, find it convex hull first.See this link
Now find the defect points between contour and its convex hull. See this link
Now using the data of defects distance, find the point with maximum distance. This point will be the points where the 2 objects are joined in L shape. Now from this point, draw a perpendicular line to the contour tangent at that point, and again find contours. The resultant contours will be the 2 contours for the L shape.
Note: In this approach, it is possible that some part of one object comes in other while dividing them at the boundary.
Ok so thanks Rahul for your answer.
I ended up finding a package that helped me trangulate the polygons which solved my issue.
download with :
pip install sect
Then :
from sect.triangulation import constrained_delaunay_triangles
Take the contours generated by openCV - this generates them as below.
Then "smooth" the colours so there are less of them. I've used this
epsilon = 0.005 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
then run it through sect
constrained_delaunay_triangles([tuple(x) for x in approx.squeeze()])
The output splits the polygons into triangles removing ALL concave polygons totally.

Converting Blender's UV vectors into 3D coordinates

I have converted a UV vector coordinates into 3D plane using Blender's Bmesh function. Using bmesh to create the newer mesh,
bm.faces.new((vert))
it creates faces that is undesirable, or more accurately, the edges and faces that are generated by the function are not as intended.
Is there a way to allow no generation of edges that are more than the maximum connected distance of a mesh using bmesh?
This picture shows generation of both edges and faces on the left marked out in green, comparing with the seam that I have marked for UV unwrapping.
Each face has a list of edges, an edge can give you it's length and if it's too long you can remove it. Removing one of the edges will also delete the face.
f = bm.faces.new((vert))
for e in f.edges:
if e.calc_length() > max_length:
bm.edges.remove(e)
You can also get the distance between two vertices before using them to create a face (v1.co-v2.co).length, the trick is knowing which will be joined as edges and which will be diagonal across the face.

Rectangle(quadrilateral) Detection by ConvexHull

I want to detect the rectangle from an image.
I used cv2.findContours() with cv2.convexHull() to filter out the irregular polygon.
Afterwards, I will use the length of hull to determine whether the contour is a rectangle or not.
hull = cv2.convexHull(contour,returnPoints = True)
if len(hull) ==4:
return True
However, sometimes, the convexHull() will return an array with length 5.
If I am using the criterion above, I will miss this rectangle.
For example,
After using cv2.canny()
By using the methods above, I will get the hull :
[[[819 184]]
[[744 183]]
[[745 145]]
[[787 145]]
[[819 146]]]
Here is my question: Given an array (Convex Hull) with length 5, how can I determine whether it is actually referring to a quadrilateral? Thank you.
=====================================================================
updated:
After using Sobel X and Y direction,
sobelxy = cv2.Sobel(img_inversion, cv2.CV_8U, 1, 1, ksize=3)
I got:
Well,
This is not the right way to extract rectangles. Since we are talking basics here, I would suggest you to take the inversion of the image and apply Sobel in X and Y direction and then run the findcontours function. Then with this you will be able to get lot of rectangles that you can filter out. You will have to apply lot of checks to identify the rectangle having text in it. Also I dont understand why do you want to force select rectangle with length 5. You are limiting the scale.
Secondly, another way is to use the Sobel X and Y image and then apply OpenCVs LineSegmentDetector. Once you get all the line segments you have to apply RANSAC for (Quad fit) so the condition here should be all the angles on a set of randomly chosen intersecting lines should be acute(roughly) and finally filter out the quad roi with text( for this use SWT or other reliable techniques).
As for your query you should select quad with ideally length 4 (points).
Ref: Crop the largest rectangle using OpenCV
This link will give you the jist of detecting the rectangle in a very simple way.
The images below give you a sort of walkthrough for inversion and sobel of image. Inversion of image eliminates the double boundaries you get from sobel.
For Inversion you use tilde operator.
Also before taking inversion also, its better you suppress the illumination artifacts. This can be done using homomorphic filtering. or taking log of an image.
It isn't so easy to fit a rectangle to a convex polygon.
You can try to find the minimum area or minimum perimeter rectangle by rotating calipers (https://en.wikipedia.org/wiki/Rotating_calipers).
Then by comparing the areas/perimeters of the hull and the rectangle, you can assess "rectangularity".

reduce perimeter of polygon by eliminating points

I don't know exactly how to state this question, so consider the following picture.
The polygons were generated by detecting contours of a rasterized map of different region boundaries. Notice the "inlets" created by letters in the original image. I'd like to identify sets of points which if the endpoints were connected would reduce the length of the polygon's perimeter by at least some value. I tried generating the convex hull for each polygon and basing the perimeter-savings on the difference in the distance between the polygon perimeter between hull vertices and the distance between the vertices but there is no guarantee that these vertices are near the edge of the "inlet".
I feel like there is a term in computational geometry for this problem but don't know what it is. Do I have to compute the distance saved for each possible combination of starting/ending points or is there a simplified algorithm which does this recursively?
An example of when using the convex hull breaks down is the polygon in the center of the following example:
Here, the convex hull connects the corners of the polygon whereas I only want to close off the large inlet on the right side of the polygon while retaining the curvature of that side.
You could try an alpha shape. Alpha shape is defined as edges in a delaunay triangulation not exceeding alpha.

Categories