What do negative coordinates mean with cv2.perspectiveTransform? - python

What do negative coordinates mean when I apply the function:
transformed_coordinates = cv2.perspectiveTransform(points, homography)
The documentation ,mentions nothing about this. Could someone please explain this?

Negative coordinates are entirely normal. That means that the projected points from 3D space to 2D image space are out of bounds or defined outside of the image boundaries. It's not documented because it's implicit.
Now you are probably wondering why you're getting these. I have no idea where points came from, but I suspect that you are visualizing some point cloud in 3D space and the transform maps visible points from the point cloud to where the camera is located. Therefore, it's perfectly normal to have points that are outside the field of view of the camera be mapped to negative coordinates which tells you they simply cannot appear or be visualized when projected to image space.

Related

Projection of point cloud on 2D image based on mesh information

I have a point cloud and meshes (vertices=points of the point cloud).
I want to project the point cloud with a certain virtual camera.
Here, since the point cloud is sparse, the rendered result includes the points which should be occluded by foreground objects.
To resolve this issue, I want to use mesh information to identify which points should be occluded.
Is there any smart way to do this in python?
Kind advice will be greatly appreciated.
After hours of searching, I conclude that I have to re-implement a novel rendering pipeline to achieve my goal.
So, instead of this, I use a mesh-based renderer to render a depth map.
And then I simply project the points of the point cloud with a projection matrix.
Here, I use the depth map to check whether the point fits with the depth or not.
If the projected point is the one that should be occluded, then the depth of the point would be larger than the depth map value at the corresponding pixel.
So, such points should be ignored while rendering.
I know that this is a less elegant and inefficient trick but anyway it works very well :)

How to get the depth coordinate in the world system from the depth camera

depth camera: intel realsense D415
language: python
I am trying to get the z coordinate of a depth point in the world coordinate system. I am wondering if there's an embedded method or if there is a way to obtain that?
Thank you in advance!
It sounds like you want to use a separate and fixed object in the scene as a reference, e.g. a table supporting your objects of interest.
Finding the 3D plane of the table is usually easy: you use some robust fitting algorithm along with reasonable priors (e.g. the largest plane, or the largest plane approximately oriented in a known way with respect to the camera).
Finding a plane, however, only gives you a "z" direction orthogonal to it, plus a translation vector to a point on the plane which may not be a desirable one. So you need a way to identify some desirable "origin" point in the point cloud. This is usually done using an object (a.k.a. "calibration jig" or "rig") of known shape that can easily be identified and precisely fit to a model. For example, a billiard ball (fit a sphere, find the center, offset by the radius to the contact point with the plane), or a cone (find the center of the base), etc. Note that using a conical jig allows to find both plane and point in one shot.

When to transform GPS co-ordinates

I have no real experience with GIS data, so when what I believed to be a simple problem has turned out to have more subtleties to it, I am dangerously unprepared!
I want to be able to classify a GPS position as inside/outside a polygon defined by GPS co-ordinates. It turns out this is the well-known (but not to me) point-in-polygon problem. I have read many questions/answers on https://gis.stackexchange.com/ (and here e.g. this).
Shapely seems a good solution, but assumes the co-ordinates are on the same cartesian plane, i.e. not GPS? So I would first need to transform my GPS points to UTM points.
Do I need to introduce this extra step, however, if the points being compared (i.e. the point and the polygon) are always going to be naturally within the same UTM zone. They should always be within the same town/city, so can I just leave them as GPS and use the lat/long co-ordinates in Shapely?
I also came across this UTM-WGS84 converter so I could convert my lat/long pairs using this package, and then use those UTM pairs in Shapely, but I would like to avoid any extra dependencies where possible.
Point-in-polygon already assumes a 2D restriction, and GPS coordinates are 3D. Right away, that gets you in trouble.
A simple workaround is to discard the GPS height, reducing it to 2D surface coordinates. Your next problem is that that your 2D surface is now a sphere. On a spherical surface, a polygon divides the surface in two parts, but there is no obvious "inside". There's a left-hand side and a right-hand side which follows from the order of points in the polygon, but neither side is the obvious "inside". Consider the equator as a trivial polygon - which hemisphere is "inside" the equator?
Next up is the issue of the polygon edges. By definition, these are straight, i.e. line segments. But lines on a spherical surface are weird - they're generally known as great circles. And any two great circles cross in exactly two points. That's not how cartesian lines behave. Worse, the equations for a great circle are not linear when expressed in GPS coordinates, because those are longitude/latitude pairs.
I can imagine that at this point you're feeling a bit confused. You might want to look at this from another side - we have a similar problem with maps. Globe maps are by definition attempts to flatten that non-flat surface. Since that's not exactly possible, you end up with map projections. You can also project the corner points of your polygons on such projections. And because the projections are flat, you can draw the edges on the projection. You now see the problem visually: On two different projections, identical polygons will contain different parts of the world!
So, since we agreed that in the real world, the edges of the polygons are great circles, we should really consider a projection that keeps the great circles straight. There's exactly one family of projections that has this property, and that's the Gnomonic projection. It's a family of projections because you can pick any point as the center.
As it happens, we have one natural point to consider here: the GPS point we're considering. If you put that in the center, draw a gnomonic projection around it, project the polygon edges, and then draw the polygon, you have an exact solution.
Except that the actual earth isn't spherical. Sorry. How exact did you need the test to be, anyway?

Find the most significant corner of a skeleton and segment the skeleton at that corner

I have images of ore seams which I have first skeletonised (medial axis multiplied by the distance transform), then extracted corners (see the green dots). It looks like this:
The problem is to find a turning point and then segment the seam by separating the seam at the turning point. Not all skeletons have turning points, some are quite linear, and the turning points can be in any orientation. But the above image shows a seam which does have a defined turning point. Other examples of turning points look like (using ASCII): "- /- _". "X" turning points don't really exist.
I've tried a number of methods including downsampling the image, curve fitting, k-means clustering, corner detection at various thresholds and window sizes, and I haven't figured it out yet. (I'm new to to using scikit)
The technique must be able to give me some value which I can use heuristically determine whether there is a turning point or not.
What I'd like to do is to do some sort of 2 line ("piecewise"?) regression and find an intersection or some sort of rotated polynomial regression, then determine if a turning point exists, and if it does exist, the best coordinate that represents the turning point. Here is my work in progress: https://gist.github.com/anonymous/40eda19e50dec671126a
From there, I learned that a watershed segmentation with appropriate label coordinates should be able to segment the skeleton.
I found this resource: Fit a curve for data made up of two distinct regimes
But I wasn't able to figure out to apply it my current situation. More importantly there's no way for me to guess a-priori what the initial coefficients are for the fitting function since the skeletons can be in any orientation.

Snap 3D cursor to an opaque part of plane (blender)

I have a question regarding python scripting in Blender, and I'd really appreciate it if someone could give me at least some conceptual guidelines to how I could do this:
Basically I have around 100 planes (simple primitive planes) and each of them has its own material and each material has it's own transparency map applied to it.
I need a way to snap each of those plane's respective pivots to their opaque parts. I.e. if there is a way to tell the following to blender through python language - "hey, go over every one of these planes, and do the following for each - snap a 3D cursor to an opaque part of the plane (it doesn't matter where exactly, as long as it's inside of an opaque part of the plane) and then snap plane's pivot point to the 3D cursor".
Of course I don't expect anyone to write me a full algorithm for this, I am just asking for a little help and a push in the right direction, as I do have experience with python, but not with blender :/
Any help would be appreciated.
You can find documentation on blender's python api here.
Within blender's image class you can access the pixel data at image.pixels as an array of floats, 4 floats per pixel (RGBA I think). image.size[0] is the width in pixels image.size[1] for height.
Given bpy.data.objects['Plane'].bound_box is an [8][3] array of points defining the outer extremes of the plane, you can locate a point on the plane for the pixel location to get the target point for the origin. You will also find bpy.data.objects['Plane'].matrix_world useful to translate the object coordinates to global.
bpy.context.scene.cursor_location = Vector((x,y,z)) will move the cursor to where you want.
bpy.ops.object.origin_set(type='ORIGIN_CURSOR') will set the active objects origin to the cursor. Note that this works on the active object, so you will need to alter your selection as you go.

Categories

Resources