numpy 如何正确地将蒙版插入到原始图像中?

hgb9j2n6  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(92)

我的目标是用圆形噪声(盐和胡椒/白色点)覆盖一张脸,然而我设法实现的只是矩形噪声。
我找到了人脸坐标(x,y,w,h)= [389, 127, 209, 209],使用这个function添加了噪声
喜欢的:

img = cv2.imread('like_this.jpg')
x,y,w,h = [389, 127, 209, 209]

noised = add_noise(img[y:y+h,x:x+w])
new = img.copy()
new[y:y+h,x:x+w]  = noised

cv2.imshow('new', new)

字符串
x1c 0d1x的数据
x,y,w,h我发现我希望我的圆在(493, 231),半径为105
我研究了一下,发现了一些关于掩码和位运算的东西,所以我尝试了:

mask = np.zeros(new.shape[:2], dtype='uint8')
cv2.circle(mask, (493, 231), 105, 255, -1)

new_gray = cv2.cvtColor(new, cv2.COLOR_BGR2GRAY)
masked = cv2.bitwise_and(new_gray, new_gray , mask=mask)

cv2.imshow('masked', masked)



这里,问题出现了:

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
OR = cv2.bitwise_or(masked, img_gray) # removes the black dots, idk why 

cv2.imshow('bitwise - OR', OR)



黑点从噪声中删除,除此之外,我似乎无法将OR转换回BGR。
也许有一个更好的方法来做到这一点。
需要帮助/指导!

6rqinv9w

6rqinv9w1#

问题是如何使用屏蔽。有两个选项,numpy和OpenCV。

numpy

由于您将噪声区域复制到结果中,现在希望恢复圆 * 外部 * 的所有内容,因此我将使用mask == 0来获得一个布尔数组,该数组在圆外部的任何地方都为真。
100d1x

的字符串
使用numpy,布尔数组可以用作索引。结果是一个“视图”,它的行为就像一个切片。通过它的操作会影响原始数据。

noised = add_noise(img[y:y+h,x:x+w])
new = img.copy()
new[y:y+h,x:x+w] = noised # whole rectangle affected

new[mask == 0] = img[mask == 0] # restore everything outside of the circle

字符串
所有三个阵列(mask, new, img)需要具有相同的形状。

OpenCV,masks

Python和numpy没有太多指向它,但它的许多C++ API都采用了一个可选的mask参数来修改该函数的操作。Mat::copyTo()就是这样一种方法。

OpenCV,按位操作

使用按位操作,掩码将不再只是将每个像素标记为真或假,而是必须是3通道,并且每个值的所有8位都计数,因此它必须仅包含0和255(0xFF)。
我会先擦除圆圈外的所有内容,然后 * 添加 * 回圆圈外的源部分。这两个操作都使用bitwise_and。需要两个操作,因为按位操作不能只是“覆盖”。它们对两个操作数都有React。我还将使用numpy的~运算符对掩码进行逐位求反。

bitwise_mask = cv.cvtColor(mask, cv.COLOR_GRAY2BGR) # blow it up
new = cv.bitwise_and(new, bitwise_mask)
new += cv.bitwise_and(img, ~bitwise_mask)


的字符串

kmpatx3s

kmpatx3s2#

按位运算在二进制条件下起作用,如果像素的值为零,则“关闭”像素,如果像素的值大于零,则“打开”像素。
在您的例子中,bitwise_or“移除”蒙版的黑色背景和噪声的黑点。
我建议这样做:

# Read image
img = cv2.imread('like_this.jpg')
x,y,w,h = [389, 127, 209, 209]

# Add squared noise
noised = add_noise(img[y:y+h,x:x+w])
new = img.copy()
new[y:y+h,x:x+w] = noised

# Transform the image to graylevel
new_gray = cv2.cvtColor(new, cv2.COLOR_BGR2GRAY)

# Create a mask in which black noise is equal to 0 and white to 2
mask = np.zeros(new.shape[:2], dtype='uint8')
mask[new_gray==0] = 1
mask[new_gray==255] = 2

# Mask the previous mask with a circle
circle = np.zeros(new.shape[:2], dtype='uint8')
circle = cv2.circle(circle, (493, 231), 105, 1, -1)
mask = mask * circle

plt.imshow(mask)
plt.show()

# Join the mask adding the noise to the image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray[mask==1] = 0
gray[mask==2] = 255

cv2.imshow('Result', gray)
cv2.waitKey(0)

字符串


的数据



希望能成功。如果你需要更多的帮助,让我知道。

相关问题