Im trying to find the minimum bounding box for a set of points. I used the library https://bitbucket.org/william_rusnack/minimumboundingbox/src/master/
I want to enclose these coordinates in the minimum bounding box :-
#INPUT COORDINATES
('297.153338872911', '373.3796368193535')
('222.75', '278.7499999999999')
('222.75', '278.7499999999999')
('42.25', '251.75')
('179.25', '390.5')
('298.403338872911', '373.3796368193535')
('0.6400000000000537', '240.0000000000201')
('75.26400000000632', '390.9120000000328')
# OUTPUT BOUNDING BOX COORDINATES , PLOTTED
[(-22.685403520024096, 373.8408037637353),
(0.6400000000000432, 240.0),
(288.84381342985046, 428.133250381587),
(312.16921694987457, 294.2924466178517)]
But as you can see from the output itself
the bounding box is coming out as tilted/inclined . That's all right, but what I want is for the bounding box to be straight to the horizontal & vertical plane of my desktop. How can I achieve this without losing the bounding box functionality (i.e. any point popping out of the bounding box while making it straight) ?
I tried this code also, but it rotates the rectangle and finds the best possible bounding box which mostly would be inclined rectangle. But I strictly want a straight rectangle.
For sake of notation, let's assume that your points are a list of pairs (2-tuples), each pair being the x,y coordinates of a point.
point_list = [(10,12), (11,14), (15,20), ...]
Your orthogonal bounding box has simply x and y limits: the min and max of each coordinate:
x_min = min(point[0] for point in point_list)
x_max = max(point[0] for point in point_list)
y_min = min(point[1] for point in point_list)
y_max = max(point[1] for point in point_list)
Your bounding box is the four edges defined by those min/max values.
Related
So after I've done object detection, I have a few overlapping 2d rectangles, and I want to find size of the area outside of all the rectangles I've created, which has (xyxy) coordinates on each one. How do I find size of area outside that boxes in python?
enter image description here
I have tried to calculate the area by adding the sizes of all the bounding boxes then the sum will be used to subtract the size from the input image. However, it is still constrained by overlapping square lengths so that the measurement is not accurate.
from bbox import BBox2D
box1 = BBox2D([0.20212765957446807, 0.145625, 0.24822695035460993, 0.10875])
box2 = BBox2D([0.6693262411347518, 0.146875, 0.31382978723404253, 0.06875])
print(box2.height * box2.width)
print(box1.height * box1.width)
Try this one.
or simply u can
def _getArea(box):
return (box[2] - box[0]) * (box[3] - box[1])
This should do the trick. Structure of Box: [xmin,ymin,xmax,ymax]
To find the area outside all of the boxes, you will need to do the following things.
Find the area of the entire image
Find the area of all of the rectangles (including overlapping area)
Find the total overlapping area
Subtract the total overlapping area from the total area of the rectangles
Subtract the rectangle area without overlap from the area of the entire image
To find the total overlapping area, you will need to loop through every rectangle on the screen and check if it is overlapping. If it is overlapping another rectangle you will need to find the corners that are overlapping each other. For example in your image, the top left and middle rectangles are overlapping. The two corners you need would be the bottom right corner of the top left rectangle and the top left corner of the middle rectangle. You can then find the area of the rectangle that is made by the overlap.
If you add a little more information in your question, I could type out a simple function that could do this but right now I don't know all the specifications.
I am currently facing a problem regarding point cloud cropping.
More specifically, I already know how to crop a point cloud based on Open3D, a package for point cloud processing. There are several ways to do it, for example:
newCamView = np.hstack((camView, np.zeros(shape=camView.shape[0]).reshape(3,1)))
vol = o3d.visualization.SelectionPolygonVolume()
vol.bounding_polygon = o3d.utility.Vector3dVector(newCamView)
vol.orthogonal_axis = "Z"
vol.axis_max = 10
vol.axis_min = -10
pcd_cropped = vol.crop_point_cloud(pcd_raw)
pcd_final = np.asarray(np.hstack((pcd_cropped.points,pcd_cropped.colors)))
But in the context of my problem, I also need to extract the points outside the volume of interest. And even after studying the Open3D documentation and searching on the internet I can't find an answer.
I would be interested in some help to either find out how to invert the selection based on a cropping method or a way to extract the specific indexes of the points that lie within the bounding volume so that I can use the function select_by_index from o3d.geometry.PointCloud to get both inliers and outliers.
You can use the Point Cloud Distance for this task. The following code should give you the points outside the crop:
dists = np.asarray(pcd_raw.compute_point_cloud_distance(pcd_cropped))
indices = np.where(dists > 0.00001)[0]
pcd_cropped_inv = pcd_raw.select_by_index(indices)
Another method to crop pointcloud in open3d is using object of class bounding box. (So this method is only for rectangular shape and not for a polygon based cropping.)
Lets create an arbitrary bounding box with center at origin, a value below 1 as edge length, and rotation R.
R = np.identity(3)
extent = np.ones(3)/1.5 # trying to create a bounding box below 1 unit
center = np.zeros(3)
obb = o3d.geometry.OrientedBoundingBox(center,R,extent) # or you can use axis aligned bounding box class
Now you can crop your point cloud (pcd) by:
cropped = pcd.crop(obb)
o3d.visualization.draw_geometries([cropped]) #press ESC to close
To get indices of points inside this bounding box:
inliers_indices = obb.get_point_indices_within_bounding_box(pcd.points)
inliers_pcd = pcd.select_by_index(inliers_indices, invert=False) # select inside points = cropped
outliers_pcd = pcd.select_by_index(inliers_indices, invert=True) #select outside points
o3d.visualization.draw_geometries([outliers_pcd])
If you already know the boundaries that you want to crop, you can create a bounding box like above and crop. Or if you want to crop w.r.t. the bounding box of another pointcloud/object (if you know pose, you can transform it and then compute bounding box of it) and use this bounding box to crop the larger point cloud. To get bounding box of point cloud:
obb = pcd.get_oriented_bounding_box(robust=False) #set robust =True for more robust computation.
aabb = pcd.get_axis_aligned_bounding_box()
So I would like to get the XY coordinates of the center of a contour on an image. How would I go about this?
I have the contours defined and the objects detected now how do I get the pixel XY of the center.
Get the normal vectors at the start and end of the contour and calculate their intersection.
^ is for a simple 3 point contour ie a circular arc. If you have more points, "center" is a kinda ambiguous term, but if you averaged all points contributing to the contour it could give you a center of mass which may be what you are after.
You could also get bounding boxes or circle etc as described here
You could also use the moments to get center of mass if you prefer as seen on the documentation:
So I have a picture with known coordinates for the four corners (lat, long) and I wish to plot some gps points on top of this.
The problem is: the image borders are not parallel to lat-long directions, so I can't use imshow's "extent" because then the corners need the same x or y.
My coordinates for the corners are (starting in bottom left corner, clockwise):
(57.786156, 14.096861) (57.786164, 14.098304)
(57.784925, 14.096857) (57.784928, 14.098310)
Can I rotate the image somehow to get lat-and long on the axis? Alternatively have a shifted coordinate system or something?
How would you do this?
imshow 'extent' and tried to transform the coordinates to [0 1] [0 1] system which seems difficult.
I'm obtaining the an ellipse by using ellipse = cv2.fitEllipse(cnt).
It returns a tuple of 3 elements, but I'm unable to find what any of that depicts. I want to find the area of the ellipse obtained. How do I do it.
Thanks!
fitEllipse returns a tuple of three elements (as you say), which define the bounding box of the ellipse. I'll use the following line to reference those elements:
(x, y), (MA, ma), angle = cv2.fitEllipse(cnt)
The only relevant information here is (MA, ma), which contains the lengths of the major axis and minor axis, in that order. The area of an ellipse is simply pi times the product of the major axis and the minor axis. (Therefore the location and rotation are irrelevant.) So you would calculate the area of this ellipse using
A = PI * MA * ma
the function cv2.fitEllipse(.) returns elements for RotatedRect that is minimum bounding rectangle covering the ellipse.
To find the area you can either get the area of the bounding rect or directly from the contour of the ellipse contourArea
You can calculate using returned elements of ellipse = cv2.fitEllipse(cnt)
Double H = ellipse.size.height;
Double W = ellipse.size.weight;
Double ellipse_area = CV_PI * (H/2.0) * (W/2.0)
Divide H and W by 2.0 for Max and Min radiuses