[英]How can I change the skin color of a human body image?
我有一張顯示皮膚的人體圖像。 假設我有另一種膚色並假設我在身體圖像中有暴露皮膚的面具,我該如何改變皮膚的顏色?
這是在 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()
所需色樣:
結果:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.