0

I need to create a numpy array that is that will indicate a filled polygon with 1s and outside is 0s. Before you say its a duplicate question. I have already checked many other questions and answers. finally got this to work with one of my cases. but when changing the 4 vertices that function is not working. i have tried to change many things in it and nothing seems to work and i simply cant understand what is the difference and why this cant work.

first i worked with

c = [[47, 187], [55, 47], [184, 186], [186, 46]]

in the first case i had some errors in the beginning. the order of the points mattered. after adding the following codes, it was working fine. here x and y are half of lenX and lenY.

t = []
    for i in range(4):
        for j in c:
            if j[0]<x and j[1]<y:
                t.append(j)
                c.pop(c.index(j))
                break
        for j in c:
            if j[0]<x and j[1]>y:
                t.append(j)
                c.pop(c.index(j))
                break
        for j in c:
            if j[0]>x and j[1]>y:
                t.append(j)
                c.pop(c.index(j))
                break
        for j in c:
            t.append(j)
            c.pop(c.index(j))
            break
    c= np.array(t)

called the function like this where lenX and lenY are always around 200 and points are within the range.

pol = create_polygon([lenX,lenY],c)

in the second case my vertices are

c = [[96, 208],[97, 91], [221, 206], [221, 85]]

now this doesn't work and i don't know why. please take a look to see if you can find something i missed.

Eshaka
  • 974
  • 1
  • 14
  • 38
  • 1
    Is there any reason why you're not using any image processing libraries for this? Also, what does "the function doesn't work" mean? Does it error? Is the output just different from what you expected? If so, what did it result in and what did you expect? What happens if the points are specified in an order such that they overlap? Note in your first 4 points, they are specified in an order that draws out a Z instead of being specified clockwise, which is probably what your algorithm expects. – alkasm Feb 18 '19 at 10:24
  • @AlexanderReynolds doesnt work means it always return an array full of 0s. there is no polygon in it. I tried your Z shape order too. still doing the same thing. the result i want is for the return array to have 1s in between the points in a shape of a polygon. – Eshaka Feb 19 '19 at 00:48
  • and any reason not to use something like OpenCV or scikit-image or similar? – alkasm Feb 19 '19 at 01:10
  • @AlexanderReynolds no specific reason. i just couldn't find the function that does what i want. what those do is draw it on the image and even that i couldn't find the function. what i want is to know the points so i can use it to do other things. its not for appearance. – Eshaka Feb 19 '19 at 01:44
  • Yes, usually drawing contours is less for looks and more for creating masks of things (say for e.g. "what is the average value inside the shape contained by these points"). Both of those libraries do this. OpenCV has `fillPoly` and `drawContours`, both of which work for this purpose, scikit-image has `draw.polygon`. I would highly suggest using one of these rather than rolling your own. – alkasm Feb 19 '19 at 03:22
  • @AlexanderReynolds thanks. i will try them – Eshaka Feb 19 '19 at 05:07

1 Answers1

1

have you updated the function according to the second answer of the question you linked? there is a problem in the first answer

the original function can work with your first set of coordinates but the second data set gives a warning of dividing by zero, modify the check function accordingly like this and it should work for all the coordinates

def check(p1, p2, base_array):
 idxs =
np.indices(base_array.shape)

 p1= p1.astype(float)
 p2= p2.astype(float)

 if p1[0] == p2[0]:
   max_col_idx = (idxs[0] - p1[0] * idxs.shape[1]
   sign = np.sign(p2[1] - p1[1])
 else:
   max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1]-p1[1]) + p1[1]
   sign = np.sign(p2[0] - p1[0])
 return idxs[1] * sign <= max_col_idx * sign
hy2kay
  • 26
  • 2