我正在尝试使用python(3.6.5)中的openCV(3.3.1)将我制作的蒙版应用于图像,以提取所有皮肤。我遍历一张照片并检查窗口,并使用两个预制的Sklearm 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行),但这没有帮助。谢谢您的帮助!
答案 0 :(得分:0)
不仅抱怨面罩的大小。它在抱怨口罩的类型。错误:
OpenCV错误:声明失败((mtype == 0 || mtype == 1)&& _mask.sameSize(* psrc1))
表示蒙版的类型或大小(在您的情况下相等)不相同。在documentation中,我们看到:
掩码 –可选操作掩码,8位单通道阵列,用于 指定要更改的输出数组的元素。
这与要求类型0(CV_8U)或1(CV_8S)的错误是一致的。
此外,即使不说,img也不应浮动,因为它不会给出理想的结果(可能无论如何都会做到)。
解决方案可能足以更改:
mask = np.zeros(img.shape[:2])
到
mask = np.zeros(img.shape[:2], dtype=np.uint8)
一个小测试显示您将获得的类型:
np.zeros((10,10)).dtype
给您dtype('float64')
,表示加倍而不是8位