Skip to content

[BUG] Drawing breaks due to cv2.findContours handling #1445

@mrariden

Description

@mrariden

When drawing, sometimes multiple contours are found for a single mask, but the code expects to encounter only a single contour.

For example:

cellpose/cellpose/gui/gui.py

Lines 1574 to 1575 in 94ae120

contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
pvc, pvr = contours[-2][0][:,0].T

and

cellpose/cellpose/gui/gui.py

Lines 1589 to 1591 in 94ae120

contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
pvc, pvr = contours[-2][0][:,0].T

and in 3d GUI:

contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
pvc, pvr = contours[-2][0].squeeze().T

and here:

contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
pvc, pvr = contours[-2][0].squeeze().T

and also in merge_cells():

cellpose/cellpose/gui/gui.py

Lines 1318 to 1320 in 94ae120

contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
pvc, pvr = contours[-2][0].squeeze().T

This error manifests when there is a small hole in a mask that is being overlapped that is right on the edge of a mask, (see image below). Presumabely there are also other edge cases when this occurs. No errors are ever seen because the add_mask() functions are called in the overriden Qt virtual methods (keyPressEvent, mouseClickEvent) which is, apparently by design.

Example breaking mask (mask is on the left with a single missing interior pixel):
Image

Two changes should be made:

  1. Handle the edge case for when multiple contours are found.
  2. Implement more robust drawing logic that will allow drawing to fail gracefully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions