'cv2 polylines can't draw on numpy array "Expected Ptr<cv::UMat> for argument 'img'"

I'm converting a pytorch tensor representation of an image and series of points to numpy so that I can draw lines between the points and display the image in jupyter lab (using matplotlib)

If I comment out the cv2.polylines line, this code works as expected, showing me the image.

    # convert img tensor to np
    img = img / 2 + 0.5
    img = img.detach().cpu().numpy().astype(np.float32)
    img = np.transpose(img, (1, 2, 0))
    print(type(img))
    # prints:
    # <class 'numpy.ndarray'>
    
    # convert label tensor to numpy ndarray
    pts = lbl.detach().cpu().numpy().reshape(-1, 1, 2)
    pts = np.rint(pts).astype(np.int32)
    print([pts])
    # prints:
    # [array([[[ 17, 153]],
    #        [[153, 154]],
    #        [[159, 692]],
    #        [[ 14, 691]]], dtype=int32)]
    
    # draw lines between the vertices in pts
    cv2.polylines(img, [pts], True, (0,255,255))

    # show the image with matplotlib.pyplot
    plt.imshow(img)
    plt.show()

However polylines gives an error:

---> 36         cv2.polylines(img, [pts], True, (0,255,255))
     37         plt.imshow(img)
     38         plt.show()

TypeError: Expected Ptr<cv::UMat> for argument 'img'

How can I draw lines on this image?

python 3.7, opencv 4.2



Solution 1:[1]

The solution was to copy the image

img = img.copy()

it seems that Tensor.numpy() actually gives you an immutable view of the underlying data structure so you can display it but not modify it. To modify it I had to create my own copy

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ezekiel