4

I am trying to apply mask on an image using opencv bitwise-not. I am able to achieve this result if I read both original and mask image in Greyscale mode, but it doesn't work on 3 channel images.

I have read this thread OpenCV Python Error: error: (-215) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function cv::binary_op but my problem isn't shapes of arrays or mask not being in uint8 format.

import cv2
import numpy as np 

img = cv2.imread("Original.png") # original image, shape 544,480,3, dtype uint8
label = cv2.imread("Mask.png") # black and white mask,shape 544,480,3, dtype uint 8
shape = img.shape # 544,480,3
black_background = np.zeros(shape=shape, dtype=np.uint8)
result = cv2.bitwise_not(img,black_background,mask=label) # this is where error occurs
cv2.imwrite("masked.png",result)

I expect the output to be original image masked with label, I get error core

OpenCV(4.0.0) C:\projects\opencv-python\opencv\modules\core\src\arithm.cpp:245: error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'

  • The only way we can reproduce your error is if you post `Original.png` and `Mask.png`. – beaker May 29 '19 at 17:56
  • Sorry but I can't post images I am using for this code as my company doesn't allow publishing our data. what I can provide is the shapes and dtypes of each image `print(img.dtype,img.shape) print(label.dtype,img.shape) print(black_background.dtype,img.shape)` code above prints following `uint8 (544, 480, 3) uint8 (544, 480, 3) uint8 (544, 480, 3)` – Andrei Tsitsvidze May 30 '19 at 10:52

1 Answers1

3

As the error hints, the problem actually is the mask shape. From the docs:

mask – optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed.

Your label is a 3-channel image, which is incompatible; that's the reason why the greyscale was working, but since your Mask.png actually is a black and white image you should go for it without any worries:

label = cv2.imread("Mask.png", cv2.IMREAD_GREYSCALE)
DLM
  • 555
  • 5
  • 10
  • Thanks for your response. I changed `label = cv2.imread("Mask.png")` with `label = cv2.imread("Mask.png",0)`. Still getting same error – Andrei Tsitsvidze May 29 '19 at 14:31
  • Could you provide me with some more information? Have you checked the image and label shapes? I have run a test right now and it's working as expected. – DLM May 29 '19 at 15:13
  • Ok. I have run this code `print(img.dtype,img.shape) print(label.dtype,img.shape) print(black_background.dtype,img.shape)` and the results are `uint8 (544, 480, 3) uint8 (544, 480, 3) uint8 (544, 480, 3)`. Hence I am reading images in with `cv.imread("path/to/image")` without other modes. – Andrei Tsitsvidze May 30 '19 at 10:56
  • And if you read the label in as a greyscale image you still get the _very_ same error? Does it happen also if you use other images? Here is my experiment: https://colab.research.google.com/drive/1Z9ivwCnjXvNYdQ-TlPEb3XjiTzi51ekM – DLM May 30 '19 at 12:03
  • Changing label image helped. I was wondering how to change output image so that it's not in negative and I simply added `img = cv2.bitwise_not(img)` right before subtracting black background form it. Thanks again for response. – Andrei Tsitsvidze May 30 '19 at 13:06