1
\$\begingroup\$

I have trained a polygon detector neural network to recognize the mask of "quadrilateral" (the mask generates curvy lines so it's not exactly a quadrilateral). I would like to get the corners of the quadrilateral.

I believe the best approach is to get the points in the mask that are closest to the corners of the image. First question is are these valid assumptions? Second question is is this the best approach?

Top-Left is minimum distance between (0,0) and mask.

Top-Right is minimum distance between (width, 0) and mask.

Bottom-Left is minimum distance between (0, height) and mask.

Bottom-Right is minimum distance between (width, height) and mask.

The last question is my implementation is slow. The Neural network generates the mask in .7 seconds, but it's taking my loop ~2 seconds to find the corners. Can this be sped up?

def predict(self,img):
    # Read image
    image = img
    height,width,channels=img.shape

    # Detect objects
    r = self.model.detect([image], verbose=0)[0]
    mask=r['masks']
    print(mask)
    x1=0
    x2=0
    x3=0
    x4=0
    y1=0
    y2=0
    y3=0
    y4=0
    minDistanceTopLeft=999999
    minDistanceTopRight=999999
    minDistanceBottomLeft=999999
    minDistanceBottomRight=999999
    xAverage=0.0
    yAverage=0.0
    for x in range(0, len(mask)):
        for y in range(0, len(mask[x])):
            if(mask[x][y]):
                distToTopLeft=(x-0)*(x-0)+(y-0)*(y-0)
                if(distToTopLeft<minDistanceTopLeft):
                    minDistanceTopLeft=distToTopLeft
                    x1=x
                    y1=y
                distToTopRight=(x-width)*(x-width)+(y-0)*(y-0)
                if(distToTopRight<minDistanceTopRight):
                    minDistanceTopRight=distToTopRight
                    x2=x
                    y2=y
                distToBottomLeft=(x-0)*(x-0)+(y-height)*(y-height)
                if(distToBottomLeft<minDistanceBottomLeft):
                    minDistanceBottomLeft=distToBottomLeft
                    x4=x
                    y4=y
                distToBottomRight=(x-width)*(x-width)+(y-height)*(y-height)
                if(distToBottomRight<minDistanceBottomRight):
                    minDistanceBottomRight=distToBottomRight
                    x3=x
                    y3=y
    toReturn=np.array([x1, y1, x2, y2, x3, y3, x4, y4, 1])
    return [toReturn.tolist()]

Mask is a numpy array of booleans (ie)

[[[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]

 [[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]

 [[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]

  ...

 [[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]

 [[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]

 [[False]
  [False]
  [False]
  ...
  [False]
  [False]
  [False]]]
\$\endgroup\$
  • \$\begingroup\$ Is my understanding correct, that you want to find an axis-aligned bounding box that encompasses all of the True values in mask? \$\endgroup\$ – 200_success Mar 5 at 0:00
  • \$\begingroup\$ Could be, I guess I need to do more research into what axis-aligned mean - I don't know if its considered a bounding box since those are normally rectangles right? Mine can be a parallelogram. Thank you for this comment though, it has given me search terms I can look into. But yes True values in mask \$\endgroup\$ – Seth Kitchen Mar 5 at 0:03
  • 1
    \$\begingroup\$ My mistake, then. It looks like you're looking for an arbitrary bounding quadrilateral (not necessarily a rectangle, and not axis-aligned). \$\endgroup\$ – 200_success Mar 5 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.