I have a set of points that all sit on a cube with side lengths a1, a2 and a3. I obtain the points by constructing a unit sphere, and then, for each point, I determine which face of a 'unit cube' the point is closest to and change the coordinate of that direction to either + or - 1. In the case of a1=a2=a3=2. I get something that looks like this:
What's the easiest/fastest way to integrate some function (scalar or vector) over this cube with some scipy or numpy function? I guess the normal for each point is very easy to construct. However, since the transformation I described above is not really smooth, I guess I'm looking for a numerical procedure. Should I just take the 6 faces, do a Delaunay triangulation and integrate, or are the better, more straight forward, ways?
Related
I am currently working with 3D geometry and I decided to use sympy.geometry to manage objects in space.
I had to solve a non-linear system of equations to find the intersection between a plane and a sphere, which yields a FiniteSet as a result (which is the correct equation of the circle, so that works). After that, I have to find the intersection between this circle and another plane, which I'm finding difficult to do as the two objects are of different type, so no direct comparison can be done.
I am asking if there is any automatic way of converting a Plane object from the module into a FiniteSet or I have to do it manually by defining a symbolic set with the coordinates of the points on the plane (which can be done as I have full description of this new plane).
Edit: By equation of the circle, I mean the following. The set is described as a collection of points (in the example, the circle is perpendicular to the z=0 plane, but this has to be done in general so few assumptions can be made to simplify the problem):
FiniteSet((70,18-sqrt(-(z-6)(z-2)),z),(70,18+sqrt(-(z-6)(z-2)),z))
Here, z is bound to be real so it is limited to the [2,4] interval.
Hello,
in my 2d software i have two inputs available:
an array of XY points
[(x,y),(1,1),(2,2),(2,3),(-1,3),...]
and another matrix representing the closed 2D bezier curve handles
[((x,y),(x,y),(x,y)),
((-1,-1),(1,1),(1,2)),
((1,1),(2,2),(2,3)),
...]
How can i check if a point is inside or outside the given curve using python ? using preferably numpy maybe
I don't know how the theory of Bezier curves, so if your second list of points is a kind of compressed way to represent a Bezier curve, first try to sample some points of the curve with the precision you want.
So you have n points of your curve, and then you can apply a simple PIP algorithm : https://en.wikipedia.org/wiki/Point_in_polygon
I can explain in details later if you want to know how to do it programmatically.
I cant write code right here, because I need the entire program to understand properly, however I may provide two approaches how to do that.
The hardest way is to approximate each Bézier curve by a polyline. And then, according to the wiki you can use two techniques:
Ray casting algorithm: the shorthand of the algorithm: You put a ray, which starting from a point and goes through the entire polygon to an another point. Some lines lies inside a polygon, some outside. And then you check to which line belongs a specific point Looks like this:
Winding number algorithm: A little bit about winding numbers. So if a winding number is non-zero, the point lies inside the polygon
The huge drawback of this approach is that the accuracy depends on how close you approximated a curve to a polyline.
The second way is to use a bitmap. For example, you set your points to the white then render the area under the curve to the black and see if your points remain white. This method is more accurate and the fastest one, because you can use the GPU for the render.
And some links related to the first a approach:
https://pomax.github.io/bezierinfo/#intersections
http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node80.html
I have a numpy array depicting a one-pixel wide, discrete, connected curve. This curve is obtained by the Skeletonization operation of image processing. I am trying to find the curvature of the above curve at an arbitrary point, to detect bends/kinks (which will have high curvature value).
I tried to implement the above using the general formula for curvature. However, since this a pixelated, discrete curve, whose generating function is unknown, I tried to resort to using numpy gradient instead.
The problem I see with the above is that, since the curve is one-pixel wide, at any point the slope can be only one of 0, 1 or infinity. As a result, the curvature values that I get are mostly meaningless or useless.
I am looking for some suggestion on where to start in order to get a smooth curve out of the above, so that I can calculate curvature in a more meaningful way. Can somebody suggest any mathematical operation or convolution that I can apply to achieve the same? Below is a representative binary image that I have.
P.S. I am very, very new to image processing, so references to standard algorithms (in math books) or library implementations would be very helpful.
An established way to do this is to fit a low-order parametric curve to each of the skeletonized points using two or more neighbouring points. Then you compute curvature at the point using the fitted curve parameters with an analytic formula. Several curve models can be used. The two main models are:
A circle. The radius of curvature, R is the reciprocal of the curvature. For a curve, it equals the radius of the circular arc which best approximates the curve at that point. You can fit a circle to a set of 2D data points using various methods. A python library that has implemented several is here.
A quadratic. This can be fitted to the point and its neighbours, then curvature can be estimated through second-order differentiation of the curve here. You can use numpy.polyfit to fit this model. A simple strategy is to first estimate the tangent vector at the point, by fitting a local line (e.g. with polyfit using an order 1 curve). The you rotate the points to align the tangent vector with the x axis. Finally you fit a 1D quadratic f(x) to the rotated points using polyfit.
The tricky thing with making any curvature estimator is that curvature can be estimated at different scales. For example, do I want my estimator to be sensitive to high frequency detail or is this actually noise? This decision manifests in the choice of neighbourhood size. Too small, and errors from noise and discretization lead to unstable estimates. However too large, and there may be large modelling error (error by approximating the curve as a parametric function). Generally you have to select the best neighbourhood size yourself.
You're also going to have some poor curvature estimates at junction points, but that's largely unavoidable as curvature is not well defined there. A naïve fix could be to segment all paths at junction points, and then estimate curvature on each path individually.
Toby gave an excellent suggestion regarding junction points: detect the junction points and take each line in between those independently.
Detecting junction points (and end points). This is quite simple: all pixels that are set and have more than two neighbors are junction points. All pixels that are set and have exactly one neighbor are end points. Detect all those points and put their coordinates in a list.
Finding the lines in between pairs of points. Starting at each coordinate in your list, look for a line starting there. Note that for the junction points, you'll have at least three lines starting there. If you do this, you'll find each line two times. You can remove duplicates by reversing the lines that end to the left of where they start (and if the two end points are on the same image column, take the one on top as the start). Now they will be directly comparable, so you can delete the duplicates (or not store them in the first place). Note that just comparing start and end point is not sufficient as you can have different lines with the same start and end points.
Tracing each line. The step above requires that you trace each line. See if you can figure it out, it's fun! Here is a description of an algorithm that traces the outline of objects, you can use it as inspiration as this problem is very similar. Store a vector with x-coordinates and one with y-coordinates for each line.
Smoothing the lines. As you noticed, consecutive steps are in one of 8 directions, so angles are strongly discretized. You can prevent this by smoothing the coordinate vectors. This is a quick-and-dirty trick, but it works. Think of these vectors as 1D images, and apply a smoothing filter (I prefer the Gaussian filter for many reasons). Here you filter the vector with x-coordinates separately from the vector with y-coordinates.
Computing the curvature. Finally, you can compute the curvature of the curve, as the norm of the derivative of the unit normal to the curve. Don't forget to take the distance between points into account when computing derivatives!
This may be a tall order, but here's what I need to be able to do...I will be given some scattered data in three dimensions (x,y,z). The end goal is to be able to have f(x,y) functions for each point on the surface. For example, given a coordinate (x,y) contained within the convex hull of the data, I would like the program to spit out f(x,y) = ax^3 + bx^2 + cx + dy^3 + ey^2 +fy + g, a bicubic function that fits the interpolated data at that point. This lead me to explore bicubic B-splines and splines in general.
I have been using SmoothBivariateSpline in the spicy.interpolate library to get the interpolated data, but I do not know where to go from here. I would like to throw out the end step all together and go straight to the intermediate step where the spline interpolation fits functions to each interval. So...I would write a program that, given a coordinate, finds out which interval it is contained in and returns a function, f(x,y), which describes the surface in that interval. Is this possible?
Cheers!
My first point is that you actually have scattered data (z) on two dimensions (x and y), if I understand you correctly.
I would write a program that, given a coordinate, finds out which interval it is contained in and returns a function, f(x,y), which describes the surface in that interval. Is this possible?
Yes, of course!
You could simply do the maths yourself (the bivariate spline might not be the most beautiful interpolation with respect to formula, but it's still somewhat manageable), or you could just get a list of coefficients, by calling get_coeffs() on the SmoothBivarianteSpline you've created. That will give you a surface-describing set of coefficients. I think the easiest way to understand the meaning of those is pointing you at the source code, so here you go; important ar tx, ty and c.
I am using Ipython Notebook. I am working on a project where I need to look at about 100 data points in 3D space and figure out the distance between each and the angle from one another. I want to see correlations of the data points and ultimately see if there is any structure to the data (a straight line hidden somewhere). I have looked into clustering techniques and hough transforms, but they seem not to give me the result I need. Any ideas are much appreciated.. thanks!
For the first issue of determining the pairwise distance between three dimensional points, you can use scipy.spatial.distance.pdist(). This will generate n(n-1)/2 distances for n points. For the second issue finding the angle between points, that's trickier. It seems so tricky that I don't even really want to think about it; however, to that end, you can use scipy.spatial.distance.cosine(), which will determine the cosine distance between two vectors.
Have you looked at scikits? I've found them very helpful in my work. http://scikit-learn.org/stable/
The distance is best found using scipy.spatial.distance.pdist() as mentioned in cjohnson318's answer. For a small array of points 'a' defined as:
import numpy as np
a=np.array([[0,0,0],[1,1,1],[4,2,-2],[3,-1,2]])
The distance euclidean distance 'D' between the points can be found as:
from scipy.spatial.distance import pdist, squareform
D = squareform(pdist(a))
In 3d polar notation, you would need 2 angles to define the direction from one point to another. It seems like a Cartesian unit vector giving the direction would likely serve your purpose just as well. These can be found as:
(a-a[:,np.newaxis,:]) / D[...,np.newaxis]
This will include NaN's in the diagonal elements, as there is no vector from a point to itself. If necessary, these can be changed to zeros using np.nan_to_num
If you actually do need the angles, you could get them by applying np.arctan to the components of the unit vector.