I have a problem using a mask to keep only few parts of an image. What I do :
1 -> Select the color I want to keep (OK)
2 -> I convert everything to Lab space to compute deltaE (OK)
3 -> Create the mask using deltaE value (OK)
4 -> Morphological opening of the mask (OK)
5 -> Apply this mask to the original image (not OK)
When I try to apply my mask to the image, I get this error :
"shape mismatch: value array of shape (720,1280,3) could not be broadcast to indexing result of shape (21045,3)"
The shape (720,1280,3) is the shape of my original image but, for the second shape, I get a different result each time I start my code.
All the data (original image and final image) are 720x1280x3 and the mask is 720x1280. Also, all the data is uint8.
Here is my code :
couleur_mire = im_Lab[mouseY,mouseX,:]
image_unie = np.ones_like(im) * couleur_mire
video.set(cv2.CAP_PROP_POS_FRAMES,frame_k)
_, im = video.read()
im_Lab = cv2.cvtColor(im, cv2.COLOR_BGR2Lab)
mask = np.zeros((h,w))
im_finale = np.zeros_like(im)
L1 = np.array(im_Lab[:,:,0],dtype=int)
a1 = np.array(im_Lab[:,:,1],dtype=int)
b1 = np.array(im_Lab[:,:,2],dtype=int)
L2 = np.array(image_unie[:,:,0],dtype=int)
a2 = np.array(image_unie[:,:,1],dtype=int)
b2 = np.array(image_unie[:,:,2],dtype=int)
deltaE =np.sqrt(np.multiply(L1-L2,L1-L2) np.multiply(a1-a2,a1-a2) np.multiply(b1-b2,b1-b2))
th = 25
mask[deltaE<th] = 1
mask = cv2.morphologyEx(mask,cv2.MORPH_OPEN,np.ones((20,20)))
mask = np.array(mask,dtype=np.uint8)
im_finale = np.zeros_like(im)
im_finale[mask==1] = im <--THIS IS THE LINE THAT DOES NOT WORK
Any help is welcome. Thanks to anyone who will take some time to answer :)
Edit : The second shape changes whenever the mask changes (if I select the same color two times in a row, the second shapes remains the same)
Edit 2 : The first value in the second shape corresponds to the number of 1 in the mask (in this case, 21045 pixels are kept with this mask)
Edit 3 : When I do it like that it works perfectly but it is too slow :
for i in range(h):
for j in range(w):
if mask[i,j]:
im_finale[i,j,:] = im[i,j,:]
CodePudding user response:
Based on my understanding you need to mask the image based on the mask you created, You can use multiplication to achieve this affect.
def mask_image( img, mask ):
newImg = img.copy()
newImg[:,:] = img[:,:] * mask[:,:]
return newImg
With this you don't have to convert the mask to uint8.