换发型算法_【AI超级美发师】深度学习算法打造染发特效(附代码)
换发型算法_【AI超级美发师】深度学习算法打造染发特效
(附代码)
原标题:【AI超级美发师】深度学习算法打造染发特效(附代码)
来源:OpenCV学堂
作者:胡耀武
【新智元导读】如今,在类似天天P图、美图秀秀等⼿机APP中,给指定照⽚或视频中的⼈物更换头发颜⾊已经是再正常不过的事情了。那么本⽂便介绍了该功能背后如AI头发分割模块、头发换⾊、颜⾊增强与修正模块等技术原理(附代码)。
⾸先,为照⽚或视频中⼈物换发⾊的算法流程如下图所⽰:国际象棋规则
AI头发分割模块
基于深度学习的⽬标分割算法已经⽐较成熟,⽐较常⽤的有FCN,SegNet,UNet,PspNet,DenseNet等等。这⾥我们使⽤Unet⽹络来进⾏头发分割,具体可以参考如下链接:点击打开链接Unet头发分割代码如下:
defget_unet_256(input _shape=(256,256,3),
num_classes=1):
inputs=Input(shape=input_shape)
#256
down0 = Conv2D(32,(3,3), padding='same')(inputs)
down0 = BatchNormalization()(down0)
down0 = Activation('relu')(down0)
down0 = Conv2D(32,(3,3), padding='same')(down0)
down0 = BatchNormalization()(down0)
down0 = Activation('relu')(down0)
down0_pool = MaxPooling2D((2,2),strides=(2,2))(down0)
#128
down1 = Conv2D(64,(3,3), padding='same')(down0_pool)
down1 = BatchNormalization()(down1)
down1 = Activation('relu')(down1)
down1 = Conv2D(64,(3,3), padding='same')(down1)
down1 = BatchNormalization()(down1)
down1 = Activation('relu')(down1)
down1_pool = MaxPooling2D((2,2),strides=(2,2))(down1)
#64
down2 = Conv2D(128,(3,3), padding='same')(down1_pool)
down2 = BatchNormalization()(down2)
down2 = Activation('relu')(down2)
down2 = Conv2D(128,(3,3), padding='same')(down2)
down2 = BatchNormalization()(down2)
down2 = Activation('relu')(down2)
down2_pool = MaxPooling2D((2,2),strides=(2,2))(down2) #32
down3 = Conv2D(256,(3,3), padding='same')(down2_pool) down3 = BatchNormalization()(down3)
down3 = Activation('relu')(down3)
down3 = Conv2D(256,(3,3), padding='same')(down3)
down3 = BatchNormalization()(down3)
down3 = Activation('relu')(down3)
down3_pool = MaxPooling2D((2,2),strides=(2,2))(down3) #16
down4 = Conv2D(512,(3,3), padding='same')(down3_pool) down4 = BatchNormalization()(down4)
down4 = Activation('relu')(down4)
down4 = Conv2D(512,(3,3), padding='same')(down4)
down4 = BatchNormalization()(down4)
down4 = Activation('relu')(down4)
down4_pool = MaxPooling2D((2,2),strides=(2,2))(down4) #8
center = Conv2D(1024,(3,3), padding='same')(down4_pool) center = BatchNormalization()(center)
center = Activation('relu')(center)
center = Conv2D(1024,(3,3), padding='same')(center) center = BatchNormalization()(center)
center = Activation('relu')(center)
感恩自然作文#center
up4 = UpSamepling2D((2,2))(center)
up4 = Concatenate([down4,up4],axis=3)
up4 = Conv2D(512,(3,3),padding='same')(up4)
up4 = BatchNormalization()(up4)
up4 = Activation('relu')(up4)
如果没有如果
up4 = Conv2d(512,(3,3),padding='same')(up4) up4 = BatchNormalization()(up4)
up4 = Activation('relu')(up4)
#16
up3 = UpSamepling2D((2,2))(up4)
up3 = Concatenate([down4,up4],axis=3)
up3 = Conv2D(256,(3,3),padding='same')(up3) up3 = BatchNormalization()(up3)
up3 = Activation('relu')(up3)
up3 = Conv2d(256,(3,3),padding='same')(up3) up3 = BatchNormalization()(up3)
up3 = Activation('relu')(up3)
#32
up2 = UpSamepling2D((2,2))(up3)
up2 = Concatenate([down4,up4],axis=3)
up2 = Conv2D(128,(3,3),padding='same')(up2) up2 = BatchNormalization()(up2)
up2 = Activation('relu')(up2)
up2 = Conv2d(128,(3,3),padding='same')(up2) up2 = BatchNormalization()(up2)
up2 = Activation('relu')(up2)
#64
up1 = UpSamepling2D((2,2))(up2)
up1 = Concatenate([down4,up4],axis=3)
up1 = Conv2D(64,(3,3),padding='same')(up1) up1 = BatchNormalization()(up1)
up1 = Activation('relu')(up1)
up1 = Conv2d(64,(3,3),padding='same')(up1) up1 = BatchNormalization()(up1)
up1 = Activation('relu')(up1)
#128
up0 = UpSamepling2D((2,2))(up1)
up0 = Concatenate([down4,up4],axis=3)
up0 = Conv2D(32,(3,3),padding='same')(up0)
up0 = BatchNormalization()(up0)
初一语文教学总结
up0 = Activation('relu')(up0)
up0 = Conv2d(32,(3,3),padding='same')(up0)
up0 = BatchNormalization()(up0)
up0 = Activation('relu')(up0)
#256
classify = Con2D(num_classes,(1,1)),activation='sigmoid')(up0)
model = Model(input=inputs,outputs=classify)
#modelpile(optimizer=RMSprop(lr=0.0001),loss=bce_dice_loss,metrices=[dice_coeff])
returnmodel
分割效果举例如下:
使⽤的训练和测试数据集合⼤家⾃⼰准备即可。
发⾊更换模块
这个模块看起来⽐较简单,实际上却并⾮如此。这个模块要细分为:
①头发颜⾊增强与修正模块;
②颜⾊空间染⾊模块;
③头发细节增强;
发⾊增强与修正模块
为什么要对头发的颜⾊进⾏增强与修正? 先看下⾯⼀组图,我们直接使⽤HSV颜⾊空间对纯⿊⾊的头发进⾏染⾊,⽬标⾊是紫⾊,结果如下:
⼤家可以看到,针对上⾯这张原图,头发⽐较⿊,在HSV颜⾊空间进⾏头发换⾊之后,效果图中很不明显,只有轻微的颜⾊变化。
为什么会出现这种情况?原因如下:我们以RGB和HSV颜⾊空间为例,⾸先来看下HSV和RGB之间的转换公式:
设 (r, g, b)分别是⼀个颜⾊的红、绿和蓝坐标,它们的值是在0到1之间的实数。设max等价于r, g和b中的最⼤者。设min等于这些值中的最⼩者。要到在HSL空间中的 (h, s, l)值,这⾥的h ∈ [0, 360)度是⾓度的⾊相⾓,⽽s, l ∈ [0,1]是饱和度和亮度,计算为:
我们假设头发为纯⿊⾊,R=G=B=0,那么按照HSV计算公式可以得到H = S = V = 0;
假设我们要把头发颜⾊替换为红⾊(r=255,g=0,b=0);
那么,我们先将红⾊转换为对应的hsv,然后保留原始⿊⾊头发的V,红⾊头发的hs,重新组合新的hsV,在转换为RGB颜⾊空间,即为头发换⾊之后的效果(hs是颜⾊属性,v是明度属性,保留原始⿊⾊头发的明度,替换颜⾊属性以达到换⾊⽬的);
HSV转换为RGB的公式如下:
对于⿊⾊,我们计算的结果是H=S=V=0,由于V=0,因此,p=q=t=0,不管⽬标颜⾊的hs值是多少,rgb始终都是0,也就是⿊⾊;
这样,虽然我们使⽤了红⾊,来替换⿊⾊头发,但是,结果却依旧是⿊⾊,结论也就是hsv/hsl颜⾊空间,⽆法对⿊⾊换⾊。
下⾯,我们给出天天P图和美妆相机对应紫⾊的换发⾊效果:
与之前HSV颜⾊空间的结果对⽐,我们明显可以看到,天天P图和美妆相机的效果要更浓,更好看,⽽且对近乎⿊⾊的头发进⾏了完美的换⾊;
由于上述原因,我们这⾥需要对图像中的头发区域进⾏⼀定的增强处理:提亮,轻微改变⾊调;
这⼀步通常可以在PS上进⾏提亮调⾊,然后使⽤LUT来处理;
经过提亮之后的上⾊效果如下图所⽰:
可以看到,基本与美妆相机和天天P图类似了。
HSV/HSL/YCbCr颜⾊空间换⾊安慰短信大全
这⼀步⽐较简单,保留明度分量不变,将其他颜⾊、⾊调分量替换为⽬标发⾊就可以了。
这⾥以HSV颜⾊空间为例:
假如我们要将头发染发为⼀半青⾊,⼀般粉红⾊,那么我们构建如下图所⽰的颜⾊MAP:
对于头发区域的每⼀个像素点P,我们将P的RGB转换为HSV颜⾊空间,得到H/S/V;
根据P在原图头发区域的位置⽐例关系,我们在颜⾊MAP中到对应位置的像素点D,将D的RGB转换为HSV颜⾊空间,得到⽬标颜⾊的h/s/v;
根据⽬标颜⾊重组hsV,然后转为RGB即可;
这⼀模块代码如下:
#h=[0,360],s=[0,1],v=[0,1]
void RGBToHSV(int R, int G, int B, float* h, float* s,float* v)
{
float min,max;
float r = R/255.0f;
float g = G/255.0f;
float b = B/255.0f;
min = MIN2(r,MIN2(g,b));
max = MAX2(r,MAX2(g,b));
if(max == min)
*h=0;
if(max == r && g >= b)
*h = 60.0f * (g-b) / (max-min);
if(max == r && g < b)
*h = 60.0f * (g-b) / (max-min) + 360.0f;
if(max == g)
*h = 60.0f * (b-r) / (max-min) + 120.0f;
if(max == b)
*h = 60.0f * (r-g) / (max-min) + 240.0f;
if(max == 0)
几点打春几点几分*s = (max-min) / max;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。