Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drawing into a numpy view with a negative step in the channel dimension doesn't work #15895

Open
tailsu opened this issue Nov 12, 2019 · 3 comments

Comments

@tailsu
Copy link
Contributor

tailsu commented Nov 12, 2019

System information (version)
  • OpenCV => opencv-contrib-python-headless==4.1.1.26
  • Operating System / Platform => OS X
Detailed description

I create three 3-channel images and draw a circle into them. In the second case I use the step trick A[:, :, ::-1] to flip the R and B channels in the image, emulating cv.cvtColor with COLOR_BGR2RGB. I then try to draw into that array. The result, as seen in the screenshot, is that nothing gets drawn. In the third case I explicitly make a copy of the channel-flipped array (which is actually a view) before drawing, and it works.

image

Expected is that cv.circle works in all three cases.

Steps to reproduce
import cv2 as cv

image1 = np.zeros((100, 100, 3), dtype='uint8')
cv.circle(image1, (50, 50), 10, (255, 255, 255), -1)

image2 = np.zeros((100, 100, 3), dtype='uint8')
image2 = image2[:, :, ::-1]
cv.circle(image2, (50, 50), 10, (255, 255, 255), -1)

image3 = np.zeros((100, 100, 3), dtype='uint8')
image3 = np.array(image3[:, :, ::-1])
cv.circle(image3, (50, 50), 10, (255, 255, 255), -1)

imshow(image1, image2, image3)
@tailsu
Copy link
Contributor Author

tailsu commented Nov 12, 2019

imshow is a custom function that wraps ipywidgets.Image, but I tried it with cv.imwrite as well and the result is the same, so it's not a visualization issue.

@alalek
Copy link
Member

alalek commented Nov 14, 2019

There is lack of support in OpenCV for numpy on-the-fly reshaped arrays. OpenCV can't even copy data back if layout is not supported.

Workaround: use return value.

-cv.circle(image2, (50, 50), 10, (255, 255, 255), -1)
+image2 = cv.circle(image2, (50, 50), 10, (255, 255, 255), -1)
image1 = 128 * np.ones((100, 100, 3), dtype='uint8')
cv.circle(image1, (50, 50), 10, (255, 255, 255), -1)

image2 = 128 * np.ones((100, 100, 3), dtype='uint8')
image2 = image2[:, :, ::-1]
cv.circle(image2, (50, 50), 10, (255, 255, 255), -1)
image2_ = cv.circle(image2, (50, 50), 10, (255, 255, 255), -1)

image3 = 128 * np.ones((100, 100, 3), dtype='uint8')
image3 = np.array(image3[:, :, ::-1])
cv.circle(image3, (50, 50), 10, (255, 255, 255), -1)

cv.imshow("1", image1)
cv.imshow("2", image2)
cv.imshow("2_", image2_)
cv.imshow("3", image3)
cv.waitKey()

@alalek
Copy link
Member

alalek commented Nov 15, 2019

With patch from #15918 we can see this message of failed conversion:

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

Unfortunately, bindings wrapper didn't fail on these arguments and did moved forward to malformed UMat overload (this is a bug).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants