首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何简单地做np.where而不包括np.where

如何简单地做np.where而不包括np.where
EN

Stack Overflow用户
提问于 2021-06-23 15:13:17
回答 2查看 154关注 0票数 1

我写了一个程序来改变照片中的肤色。

首先我得到一个皮肤面罩,然后我把BGR图像转换为HSV。在掩码中添加V通道值。如下所示:

代码语言:javascript
复制
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个。

所以我试着:

代码语言:javascript
复制
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。非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-23 17:23:19

使用skin_mask作为掩码可能更优雅,而不是应用像skin_mask / 255 * 50这样的算术。

你可以用cv2.add来解决这个问题

代码语言:javascript
复制
NV = V.copy()
cv2.add(NV, np.full_like(V, 50), NV, mask=skin_mask)

使用cv2.add优于NumPy算法的优点:

  • cv2.add支持mask参数(掩码元素值通常是0255)。
  • cv2.add将结果剪辑到有效范围uint8 0,255,没有溢出。

用于测试解决方案的代码:

代码语言:javascript
复制
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()
票数 3
EN

Stack Overflow用户

发布于 2021-06-23 15:47:59

您仍然需要检测溢出。稍微干净一点的方法是使用np.minimumnp.clip

代码语言:javascript
复制
brighter_V = np.minimum(V + skin_mask / 255 * 50, 255)
NV = np.where(skin_mask > 0, brighter_V, V).astype(np.uint8)

np.clip方法甚至更通用,以防值溢出到0以下:

代码语言:javascript
复制
brighter_V = np.clip(V + skin_mask / 255 * 50, 0, 255)
NV = np.where(skin_mask > 0, brighter_V, V).astype(np.uint8)

(两行的间隔只是我个人的编码偏好)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68102563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档