python - 如何简单地做 np.where 不包括 np.where
问题描述
我写了一个程序来改变照片中皮肤的颜色。
首先我得到一个皮肤蒙版,然后我将 BGR 图像转换为 HSV。在掩码中添加 V 通道值。像这样:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
H, S, V = cv2.split(hsv)
NV = np.where(skin_mask > 0, V + skin_mask / 255 * 50, V).astype(np.uint8)
NHSV = cv2.cvtColor(cv2.merge([H, S, NV]), cv2.COLOR_HSV2BGR)
但是一些原来的白色像素变成了黑色,我想也许 V + skin_mask / 255 * 50 让像素超过 255。
所以我尝试:
NV = np.where(skin_mask > 0, np.where(V + skin_mask / 255 * 50 > 255, 255, V + skin_mask / 255 * 50), V).astype(np.uint8)
这是工作。但丑陋。
我想知道如何美化这篇文章,不要使用np.where包括np.where。非常感谢你!!!
解决方案
用作掩码可能更优雅skin_mask
,而不是像skin_mask / 255 * 50
.
您可以使用cv2.add解决它:
NV = V.copy()
cv2.add(NV, np.full_like(V, 50), NV, mask=skin_mask)
cv2.add
使用NumPy 算法的优点:
cv2.add
支持mask
参数(掩码元素值通常是0
and255
)。cv2.add
将结果剪辑到 uint8 [0, 255] 的有效范围内,不会溢出。
我用于测试解决方案的代码:
import numpy as np
import cv2
# Build sample skin_mask
skin_mask = np.zeros((100, 80), np.uint8)
skin_mask[30:70, 30:60] = 255
# Build sample V matrix
V = np.full_like(skin_mask, 60)
V[40:80, 40:80] = 220
# Sum using cv2.add
NV = V.copy()
cv2.add(NV, np.full_like(V, 50), NV, mask=skin_mask)
# Sum using NumPy (used as reference for testing).
refNV = np.where(skin_mask > 0, np.minimum(V + skin_mask / 255 * 50, 255), V).astype(np.uint8) # Reference
if np.any(NV != refNV):
print('There is a bug: NV != refNV') # Should not enter here
# Show the images
cv2.imshow('skin_mask', skin_mask)
cv2.imshow('V', V)
cv2.imshow('NV', NV)
cv2.imshow('refNV', refNV)
cv2.waitKey()
cv2.destroyAllWindows()
推荐阅读
- javascript - 在字符串JS中添加变量
- sql-server - 如何使sqlcmd导出的每一行数据在csv文件中的一行中显示
- java - 将 bundle.getString() 的结果分配给 String 会引发 ClassCastException
- kubernetes - kubelet 是否验证 PodSecurityPolicy?
- excel - 如何将分隔文本提取到列中,不包括某些文本
- android - 使用“Glide”将图片带到“Android gridview”时非常慢
- regex - 禁止以“.”开头的单词
- terraform - 有没有办法让 terraform 忽略 ResourceNotFoundException 并破坏其他资源
- javascript - 时刻 isBetween 返回 false
- android - 如何使用共享状态检索图像并将其显示在 Android Studio 的图像视图中?