1

Using python, given a numpy array of point vertices and center of mass, how do I find the most upper left vertex (along the 45 degree axis), upper right, bottom left, and bottom right vertex?

Its easy to find the most Right or Highest, (its just the Max X coordinate, or Max Y)

In this example, (6,7) is not the most left as (4,10), or highest (10,5); however its most upper-left.

I want to be able to extend, and quickly sort what is second, or third closest to upper left.

Note: Sometimes the coordinates may not directly lie on the 45deg axis .

enter image description here

Currently using Python, with numpy and opencv.

Note: "Its easy to find the most Right or Highest, (its just the Max X coordinate, or Max Y) " If there is way to change the frame of reference, to a 45 degree axis angle, they can find most top left or top right correspondingly. Trying to find way to conduct this,

Update: Reviewing this example, want to extend it to bottom left and bottom right

https://stackoverflow.com/a/64659569/15435022

is bottom left as this?

bottom_left = sorted(keypoints_to_search, key=lambda p: (-p.pt[0]) - (p.pt[1]))[0] 
mattsmith5
  • 540
  • 4
  • 29
  • 67
  • 2
    "(3,8) is not the most left (5)" -- 3 is less than 5, so it is further left than (5,10). You illustration is incorrect, either that point is in the wrong location or its coordinates are wrong. – Dan Mašek Apr 02 '21 at 10:53
  • hi @DanMašek thanks just fixed – mattsmith5 Apr 02 '21 at 16:33
  • OK. So now, what's your definition of the top-left most point? What mathematical properties does this point have? What would be the absolute top-left most in this case (i.e. where are we measuring from)? What about the top-right? | Let's set the origin to (0,0) for convenience. Let's say we have 3 points, all at the same distance from origin : `(0,1)`, `(1,0)`, `(sqrt(0.5), sqrt(0.5))`. Which is the top-right most one of those? Let's change the third point to `(1-sqrt(0.5), 1-sqrt(0.5))`, so that everything is at the same distance from `(1,1)`. Which is the top-right most now? Why? – Dan Mašek Apr 02 '21 at 17:41
  • hi @DanMašek placed in question, Note: "Its easy to find the most Right or Highest, (its just the Max X coordinate, or Max Y) " If there is way to change the frame of reference (point of relativity), to a 45 degree axis angle, they can find most top left or top right correspondingly. Trying to find way to conduct this, – mattsmith5 Apr 02 '21 at 17:43
  • Oh, just a simple transformation of the coordinates. [`getRotationMatrix2D`](https://docs.opencv.org/4.5.1/da/d54/group__imgproc__transform.html#gafbbc470ce83812914a70abfb604f4326) and then use it to [`transform`](https://docs.opencv.org/4.5.1/d2/de8/group__core__array.html#ga393164aa54bb9169ce0a8cc44e08ff22). | https://pastebin.com/d6g5TXem | https://i.imgur.com/pnZrKYJ.png | Like that? (Took a lot longer to make the visualization :D ) – Dan Mašek Apr 02 '21 at 18:22
  • I also left a partial answer here? would that work? https://stackoverflow.com/a/64659569/15435022 @DanMašek – mattsmith5 Apr 02 '21 at 18:24
  • Yes, `min(x+y)` and `max(x-y)` will do the same thing as rotating 45 degrees counterclockwise and doing `min(x)` and `min(y)`. | However, based on this metric, the most upper-left point out of those 3 candidates is `(4,10)` (the other two add up to 15). – Dan Mašek Apr 02 '21 at 18:54
  • hi @DanMašek ok, thanks, I extended question to bottom left and bottom right, feel free to place in answer, and I can send points, thanks for help – mattsmith5 Apr 02 '21 at 18:58
  • Bottom right has both `x` and `y` at their maximum, so `max(x+y)`. Bottom left has highest `y` and the smallest `x`, so `max(y-x)`. – Dan Mašek Apr 02 '21 at 19:04

1 Answers1

3

The other stackoverflow answer that you have updated in your question answers this beautifully.

Essentially what you're looking for can be put up in a python function like below:-

def order_points(pts):
    # initialzie a list of coordinates that will be ordered
    # such that the first entry in the list is the top-left,
    # the second entry is the top-right, the third is the
    # bottom-right, and the fourth is the bottom-left
    rect = np.zeros((4, 2), dtype = "float32")

    # the top-left point will have the smallest sum, whereas
    # the bottom-right point will have the largest sum
    s = pts.sum(axis = 1)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]

    # now, compute the difference between the points, the
    # top-right point will have the smallest difference,
    # whereas the bottom-left will have the largest difference
    diff = np.diff(pts, axis = 1)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]

    # return the ordered coordinates
    return rect

Ref: https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

KaranKakwani
  • 160
  • 12