I'm stuck at this tutorial where a ROI is pasted over another region of same image. Python trows a value error when I try something similar:
img = cv2.imread(path, -1)
eye = img[349:307, 410:383]
img[30:180, 91:256] = eye
Exeption:
Traceback (most recent call last):
File "test.py", line 13, in <module>
img[30:180, 91:256] = eye
ValueError: could not broadcast input array from shape (0,0,3) into shape (150,165,3)
This might be very newb question, but I couldn't come up with an answer by searching on google. Are there other numpy methods for doing this?
EDIT: Also in the tutorial its not specified how the coordinates should be entered. Ex: I can enter coords of the region I want something like: eye = img[x1:y1, x2:y2]
or img[x1:x2, y1:y2]
. This is what confusing to me. Actually I tried to get these coords from a mouse callback method which printed the position of the mouse click. So, the coordinates are surely from the inside of image.
I would guess that there's something off with your image. Let's look at the error returned
ValueError: could not broadcast input array from shape (0,0,3) into shape (150,165,3)
So eye appears to have the dimension (0,0,3) and img has the dimension (150,165,3). The 3 corresponds to RGB which is the 3 different color channels. So your original image is 150x165. But you tried to select a region at img[349:307, 410:383]. I suspect since the region you specified is outside the image it is not selecting anything hence the dimensions (0,0,3).
Try import pdb; pdb.set_trace() after the second line where you initialize eye. This will pop you into an interactive python terminal where you can see what's going on. Try to see what the dimensions of img are and if it's really what you want. Maybe the image you downloaded is smaller than the example causing the error.
Check out the first answer to a similar question. Your method for getting roi looks correct so try just adjusting the coordinates to a smaller region that fits.
Your slice [349:307, 410:383]
returns an empty array eye
, which could not be assigned to an array view of different shape.
E.g.:
In [8]: import cv2
...: fn=r'D:\Documents\Desktop\1.jpg'
...: img=cv2.imread(fn, -1)
...: roi=img[200:400, 200:300]
In [9]: roi.shape
Out[9]: (200, 100, 3)
In [10]: img2=img.copy()
In [11]: img2[:roi.shape[0], :roi.shape[1]]=roi
In [12]: cv2.imshow('img', img)
...: cv2.imshow('roi', roi)
...: cv2.imshow('img2', img2)
...: cv2.waitKey(0)
...: cv2.destroyAllWindows()
result:
img & roi:
img2:
NOTE that even if roi
is not an empty array, assignment with mismatching shapes will raise errors:
In [13]: img2[:100, :100]=roi
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-13-85de95cf3ded> in <module>()
----> 1 img2[:100, :100]=roi
ValueError: could not broadcast input array from shape (200,100,3) into shape (100,100,3)
img[349:307, 410:383]
is asking for the interpreter to find all the x values above 349 AND below 307, which is impossible, and will return a slice size 0. Turn your numbers around.
img[307,349, 383:413]
Also your dimensions are wrong. How can you put a slice of width 42 into a slice of width 150?