0

Why cv2.line can't draw on 1 channel numpy array slice inplace?

print('cv2.__version__', cv2.__version__)

# V1
print('-'*60)
a = np.zeros((20,20,4), np.uint8)
cv2.line(a[:,:,1], (4,4), (10,10), color=255, thickness=1)
print('a[:,:,1].shape', a[:,:,1].shape)
print('np.min(a), np.max(a)', np.min(a), np.max(a))

# V2
print('-' * 60)
b = np.zeros((20,20), np.uint8)
cv2.line(b, (4,4), (10,10), color=255, thickness=1)
print('b.shape', b.shape)
print('np.min(b), np.max(b)', np.min(b), np.max(b))

Output:

cv2.__version__ 4.1.0
------------------------------------------------------------
a[:,:,1].shape (20, 20)
np.min(a), np.max(a) 0 0
------------------------------------------------------------
b.shape (20, 20)
np.min(b), np.max(b) 0 255

Seems error message depends on opencv version:

cv2.__version__ 3.4.3
------------------------------------------------------------
Traceback (most recent call last):
  File "test_me.py", line 11, in <module>
    cv2.line(a[:,:,1], (4,4), (10,10), color=255, thickness=1)
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
mrgloom
  • 20,061
  • 36
  • 171
  • 301

1 Answers1

1

Interesting question. Given the error:

Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)

I think this may be caused by the difference between views / copies in numpy. read1 read2

For comparison, the following does not work:

x = a[:,:,1]
cv2.line(x, (4,4), (10,10), color=255, thickness=1)
a[:,:,1] = x

While the following does:

x = np.copy(a[:,:,1])
cv2.line(x, (4,4), (10,10), color=255, thickness=1)
a[:,:,1] = x
J.D.
  • 4,511
  • 2
  • 7
  • 20