【问题标题】:How can I change the skin color of a human body image?如何更改人体图像的肤色?
【发布时间】:2021-04-23 23:04:27
【问题描述】:

我有一张显示皮肤的人体图像。假设我有另一种肤色并假设我在身体图像中有暴露皮肤的蒙版,我该如何更改皮肤的颜色?

【问题讨论】:

标签: python opencv python-imaging-library


【解决方案1】:

这是在 Python/OpenCV 中执行此操作的一种方法。我不确定它有多强大。

基本上,我们得到人脸的平均颜色。获取该颜色与所需颜色之间的差异颜色(在每个通道中)。然后我们将差异添加到输入图像中。然后我们使用遮罩将原始图像和新图像结合起来。

输入:

面罩:

import cv2
import numpy as np
import skimage.exposure

# specify desired bgr color for new face and make into array
desired_color = (180, 128, 200)
desired_color = np.asarray(desired_color, dtype=np.float64)

# create swatch
swatch = np.full((200,200,3), desired_color, dtype=np.uint8)

# read image
img = cv2.imread("zelda1.jpg")

# read face mask as grayscale and threshold to binary
facemask = cv2.imread("zelda1_facemask.png", cv2.IMREAD_GRAYSCALE)
facemask = cv2.threshold(facemask, 128, 255, cv2.THRESH_BINARY)[1]

# get average bgr color of face
ave_color = cv2.mean(img, mask=facemask)[:3]
print(ave_color)

# compute difference colors and make into an image the same size as input
diff_color = desired_color - ave_color
diff_color = np.full_like(img, diff_color, dtype=np.uint8)

# shift input image color
# cv2.add clips automatically
new_img = cv2.add(img, diff_color)

# antialias mask, convert to float in range 0 to 1 and make 3-channels
facemask = cv2.GaussianBlur(facemask, (0,0), sigmaX=3, sigmaY=3, borderType = cv2.BORDER_DEFAULT)
facemask = skimage.exposure.rescale_intensity(facemask, in_range=(100,150), out_range=(0,1)).astype(np.float32)
facemask = cv2.merge([facemask,facemask,facemask])

# combine img and new_img using mask
result = (img * (1 - facemask) + new_img * facemask)
result = result.clip(0,255).astype(np.uint8)

# save result
cv2.imwrite('zelda1_swatch.png', swatch)
cv2.imwrite('zelda1_recolor.png', result)

cv2.imshow('swatch', swatch)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

所需的色板:

结果:

【讨论】:

  • Fred - 希望“粉红色”与StackOverflow's Code of Conduct 一致。 ;-)
  • @HansHirse 感谢您的链接。我不知道那件事。但如果它冒犯任何人或删除示例,我可以将颜色更改为其他颜色。没有不尊重的意思,这是一张公开的图片(塞尔达)。
  • 抱歉,口罩是怎么弄到的?
  • @George Bora 抱歉,时间太长了。但很可能是手动追踪的。
【解决方案2】:
import cv2
import numpy as np
import skimage.exposure



#usage
#put this script and the image face.jpg in the same directory /dir
#run these 2 commands inside bash
#cd /dir
#python change_skin_v1.py

#script_name= change_skin_v1.py


#you can change  the 3 parameters: alpha, skincolor_low, skincolor_high


#path file
path_face="./face.jpg"
result_partial="./result_partial.png"
result_final="./result_partial.png"


#blending parameter
alpha = 0.7


# Define lower and uppper limits of what we call "skin color"
skincolor_low=np.array([0,10,60])
skincolor_high=np.array([180,150,255])



#specify desired bgr color (brown) for the new face.
#this value is approximated
desired_color_brg = (2, 70, 140)




# read face
img_main_face = cv2.imread(path_face)



# face.jpg has by default the BGR format, convert BGR to HSV
hsv=cv2.cvtColor(img_main_face,cv2.COLOR_BGR2HSV)




#create the HSV mask
mask=cv2.inRange(hsv,skincolor_low,skincolor_high)



# Change image to brown where we found pink
img_main_face[mask>0]=desired_color_brg
cv2.imwrite(result_partial,img_main_face)




#blending block start

#alpha range for blending is  0-1


# load images for blending
src1 = cv2.imread(result_partial)
src2 = cv2.imread(path_face)

if src1 is None:
    print("Error loading src1")
    exit(-1)
elif src2 is None:
    print("Error loading src2")
    exit(-1)
    
    
# actually  blend_images
result_final = cv2.addWeighted(src1, alpha, src2, 1-alpha, 0.0)
cv2.imwrite('./result_final.png', result_final)

#blending block end

【讨论】:

    猜你喜欢
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2011-04-11
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多