简体   繁体   中英

RGB image masking using opencv and numpy arrays (shape mismatch)

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,:]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM