皮肤检测与抠图
皮肤检测的方法很多,这里写的是最简单的方法,感兴趣的同学可以自己加上椭圆检测,膨胀腐蚀等,使得检测与抠图更加精确。github上许多人脸识别的算法,可以多学习那些。
HSV颜色空间
hsv涉及心理学的颜色知识,比rgb检测具有更好的分类效果
python 代码
def get_skin_hsv(img)
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
back = np.zeros(img.shape, np.uint8)
(h, s, v) = cv2.split(hsv_img)
(x, y) = h.shape
for i in range(x):
for j in range(y):
if (h0[i][j] > 0) and (h0[i][j] < 20) and (s0[i][j] > 48) and (s0[i][j] < 255) and (v0[i][j] > 50) and (v0[i][j] < 255):
back[i][j] = img[i][j]
return back
效果
本来放图了,后来想想放别人的图都不合适,感兴趣的大佬自己去试吧。
YUV
yuv色彩空间是考虑人眼对亮谙更敏感的特性,在数据存储,传输时的省去部分信息存储的方法。用于皮肤检测效果也挺好。https://www.cnblogs.com/ALittleDust/p/5935983.html这篇博文对yuv的讲解很详细,感兴趣的同学可以去看。
python代码
def get_skin_yuv(img)
ycrcb_img = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
(y, cr, cb) = cv2.split(ycrcb_img)
(x, y) = cr.shape
back = np.zeros(img.shape, np.uint8)
for i in range(x):
for j in range(y):
if (cr[i][j] > 133) and (cr[i][j] < 173) and (cb[i][j] > 77) and (cb[i][j] < 127):
back[i][j]=img[i][j]
img[i][j]=0 #这样做是为了让原图与滤波后的图合成时更准确
return back
效果
感兴趣的大佬自己试吧。
磨皮美颜
磨皮美艳的关键是用什么函数进行滤波,以及参数的设置。如果美图秀秀或者PS开源的话,我想开源社区能把美艳修图发挥到极致。
参考网上大佬的做法,我也选择双边滤波和高斯滤波。
考虑到参数太难调试的问题,我设置了一个滑动条,方便手动调节参数。代码中仅提供了双边滤波的参数设置条,对高斯滤波的参数设置,原理一样。
python滑动条
"""
a,b,c分别接受滑动条位置信息,作为双边滤波的参数d,sigmaColor,sigmaSpace
"""
def noting(x):
pass
cv2.namedWindow('image')
cv2.createTrackbar('d','image',0,50,noting)
cv2.createTrackbar('sigmaColor', 'image', 0, 255,noting)
cv2.createTrackbar('sigmaSpace', 'image', 0, 255,noting)
a = cv2.getTrackbarPos('d', 'image')
b = cv2.getTrackbarPos('sigmaColor', 'image')
c = cv2.getTrackbarPos('sigmaSpace', 'image')
双边滤波和高斯滤波
"""
对我们的皮肤抠图back0单独滤波,这样可以保证背景不在转换过程中失真。最后要与原图合起来
"""
img0 = np.zeros(img.shape, np.uint8)
infmg_1 = np.zeros(img.shape, np.uint8)
infmg_2 = np.zeros(img.shape, np.uint8)
infmg_3 = np.zeros(img.shape, np.uint8)
infmg_4 = np.zeros(img.shape, np.uint8)
while (1):
key = cv2.waitKey(1)
if key > 0:
break
a2 = cv2.getTrackbarPos('d', 'image')
b2 = cv2.getTrackbarPos('sigmaColor', 'image')
c2 = cv2.getTrackbarPos('sigmaSpace', 'image')
if a2!=a or b2!=b or c2!=c:
cv2.bilateralFilter(back0, a, b, c, infmg_1)
a,b,c=a2,b2,c2
dst1 = infmg_1 - back0 + 128
# cv2.imshow("双边滤波", dst1)
infmg_2 = cv2.GaussianBlur(dst1, (1, 1), 0, 0)
infmg_3 = back0 + 2 * infmg_2 - 255
# cv2.imshow("高斯滤波", infmg_3)
infmg_4 = cv2.addWeighted(back0, 0.2, infmg_3, 0.8, 0)
img0 = cv2.add(img, infmg_4) #img是原图,infmg_4是最终滤波的结果
cv2.imshow("美颜结果", img0)
cv2.imwrite("美颜结果.jpg", img0)
while 1:
key = cv2.waitKey(1)
if key > 0:
break
cv2.destroyAllWindows()
效果
本来放图了,后来想想放别人的图都不合适,感兴趣的大佬自己去试吧。