【问题标题】:How to simply do np.where not includes np.where如何简单地做 np.where 不包括 np.where
【发布时间】:2021-06-23 15:13:17
【问题描述】:

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

首先我得到一个皮肤遮罩,然后我将 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。非常感谢!!!

【问题讨论】:

    标签: python numpy opencv


    【解决方案1】:

    使用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 参数(掩码元素值通常为0255)。
    • 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()
    

    【讨论】:

      【解决方案2】:

      您仍然需要检测溢出。更简洁的方法是使用np.minimumnp.clip

      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 以下:

      brighter_V = np.clip(V + skin_mask / 255 * 50, 0, 255)
      NV = np.where(skin_mask > 0, brighter_V, V).astype(np.uint8)
      

      (分成两行只是我个人的编码偏好)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-17
        • 2019-10-03
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 2019-03-10
        相关资源
        最近更新 更多