pythonopencvconvex-hull

Why cv.convexityDefects fails in this example? Is it a bug?


This script:

import numpy as np, cv2 as cv

contour = np.array([[0, 0], [1, 0], [1, 1], [0.5, 0.2], [0, 0]], dtype='f4')
hull = cv.convexHull(contour, returnPoints=False)
defects = cv.convexityDefects(contour, hull)

fails and produces this error message:

  File "/home/paul/upwork/pickleball/code/so-65-ocv-convexity-defects.py", line 5, in <module>
    defects = cv.convexityDefects(contour, hull)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cv2.error: OpenCV(4.11.0) /io/opencv/modules/imgproc/src/convhull.cpp:319: error: (-215:Assertion failed) npoints >= 0 in function 'convexityDefects'

What is the reason? Here is a plot of contour:

enter image description here

And hull is:

[[0]
 [1]
 [2]]

Solution

  • I couldn't find confirmation for that in the documentation,
    but convexityDefects expects the points coordinates in contour to be int32 rather than floating points.

    The following code works as expected:

    import cv2 as cv
    import numpy as np
    
    contour = np.array([[0, 0], [10, 0], [10, 10], [5, 2], [0, 0]], dtype=np.int32)
    hull = cv.convexHull(contour, returnPoints=False)
    defects = cv.convexityDefects(contour, hull)
    print(defects)
    

    Output:

    [[[  2   0   3 543]]]
    

    Note that the result is a 4 elements vector: (start_index, end_index, farthest_pt_index, fixpt_depth) and the last element in the result vector (that seem relatively large) is fixpt_depth:

    fixed-point approximation (with 8 fractional bits) of the distance between the farthest contour point and the hull. That is, to get the floating-point value of the depth will be fixpt_depth/256.0.