Ошибка OpenCV: bitwise_and выдает ошибку, что маска и изображение не имеют одинаковый размер

1

Я пытаюсь применить маску, которую я сделал для изображения, используя openCV (3.3.1) в python (3.6.5), чтобы извлечь весь скин. Я перебираю фотографии и проверяю окна и классифицирую их, используя два готовых GMM. Если окно - это скин, я изменяю эту область маски на True (255), оставив ее равной 0.

Я инициализировал массив numpy, чтобы удерживать маску до того, как цикл будет таким же размером, как и изображение, но openCV продолжает говорить, что изображение и маска не имеют одинаковых размеров (вывод и сообщение об ошибке ниже). Я видел другие похожие проблемы на сайте, но ни один из них не работал со мной.

Вот мой код:

# convert the image to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
delta = 6
# create an empty np array to make the mask
#mask = np.zeros((img.shape[0], img.shape[1], 1))
mask = np.zeros(img.shape[:2])
# loop through image and classify each window
for i in range(0,hsv.shape[0],delta):
    for j in range(0,hsv.shape[1],delta):
        # get a copy of the window
        arr = np.copy(hsv[i:i+delta,j:j+delta,0])
        # create a normalized hue histogram for the window
        if arr.sum() > 0:
            arr = np.histogram(np.ravel(arr/arr.sum()), bins=100, range=(0,1))
        else:
            arr = np.histogram(np.ravel(arr), bins=100, range=(0,1))
        # take the histogram and reshape it
        arr = arr[0].reshape(1,-1)
        # get the probabilities that the window is skin or not skin
        skin = skin_gmm.predict_proba(arr)
        not_skin = background_gmm.predict_proba(arr)
        if skin > not_skin:
            # becasue the window is more likely skin than not skin
            # we fill that window of the mask with ones
            mask[i:i+delta,j:j+delta].fill(255)
# apply the mask to the original image to extract the skin
print(mask.shape)
print(img.shape)
masked_img = cv2.bitwise_and(img, img, mask = mask)

Выход:

(2816, 2112)
(2816, 2112, 3)
OpenCV Error: Assertion failed ((mtype == 0 || mtype == 1) && 
_mask.sameSize(*psrc1)) in cv::binary_op, file C:\ci\opencv_1512688052760
\work\modules\core\src\arithm.cpp, line 241
Traceback (most recent call last):
File "skindetector_hist.py", line 183, in <module>
main()
File "skindetector_hist.py", line 173, in main
skin = classifier_mask(img, skin_gmm, background_gmm)
File "skindetector_hist.py", line 63, in classifier_mask
masked_img = cv2.bitwise_and(img, img, mask = mask)
cv2.error: C:\ci\opencv_1512688052760\work\modules\core\src
\arithm.cpp:241: error: (-215) (mtype == 0 || mtype == 1) && 
_mask.sameSize(*psrc1) in function cv::binary_op

Как вы можете видеть на выходе, изображение и маска имеют одинаковую ширину и высоту. Я также попытался сделать маску глубиной один (строка 5), но это не помогло. Спасибо за любую помощь!

Теги:
opencv
image-processing

1 ответ

0
Лучший ответ

Он не только жалуется на размер маски. Он жалуется на тип маски. Ошибка:

Ошибка OpenCV: утверждение не выполнено ((mtype == 0 || mtype == 1) && _mask.sameSize(* psrc1))

Значит, что либо тип маски, либо размер (который в вашем случае равен) не совпадают. В документации мы видим:

mask - необязательная рабочая маска, 8-битный одноканальный массив, который определяет элементы выходного массива, который нужно изменить.

И это согласуется с ошибкой, которая запрашивает тип 0 (CV_8U) или 1 (CV_8S).

Кроме того, даже если это не сказано, img не должен быть float, так как он не даст желаемого результата (возможно, он будет делать это в любом случае).

Решение, вероятно, достаточно, чтобы изменить:

mask = np.zeros(img.shape[:2])

в

mask = np.zeros(img.shape[:2], dtype=np.uint8)

Небольшой тест показывает, какой тип вы получите:

np.zeros((10,10)).dtype

дает вам dtype('float64') что означает удвоение, а не 8 бит

Ещё вопросы

Сообщество Overcoder
Наверх
Меню