- 金属破碎机
- 破石机
- 石头破碎机
- 颚式破碎机
- 反击式破碎机
- 锤式破碎机
- 复合式破碎机
- 冲击式破碎机
- 立式复合破碎机
- 重锤式破碎机
- 花岗岩石破碎机
- 高效破碎机
- 双齿破碎机
- 煤矸石破碎机
- 四辊破碎机
- 环锤式破碎机
- 小型破碎机
- 双轴破碎机
- 单辊式破碎机
- 对辊式破碎机
- 圆锥式破碎机
- 振动给料机
- 圆振动筛
- 斗式提升机
- 直线振动筛
- 电磁振动给料机
- 滚筒筛沙机
- 高频筛
- 振动筛
- 滚筒洗石机
- 干式磁选机
- 螺旋溜槽
- 螺旋分级机
客户购机前,企业免费派工程技术人员到用户现场为用户规划场地、...
- 还记得吗?去年冬天,在国外AI圈有个事情闹得很火:知名论坛Reddit上忽然出现一个叫deepfakes的大神,借助神经网络实现了人脸替换,让一些好莱坞女星“出演”了AV。后来根据这个项目又衍生了一个叫FakeAPP的桌面应用,可以让尼古拉斯·凯奇这样的明星随心所欲的“出演”任何影片,当然换成任何人的脸部都可以。十大正规网投平台曾详细分享过这些项目:景略集智:大意了!居然有人用AI技术制作假AV!景略集智:AI已经决定了,ta就是未来每一届奥斯卡最佳男主。怎么样,是不是被这种换脸的效果惊到了?其实即便是不借助神经网络,十大正规网投平台用Python和一些Python库也能实现换脸,只不过替换的是静态图像中的人脸,但凭此也足以显示出Python的“神秘力量”。十大正规网投平台下面就传授一下这门Python“换脸”大法。在本文,十大正规网投平台会先容如何通过一段简短的Python脚本(200行)将一张图片中面部特征自动替换为另外一张图片中的面部特征。也就是实现下面这样的效果:具体过程分为四个步骤:检测面部标志;旋转、缩放和平移图2以适应图1;调整图2的白平衡以匹配图1;将图2的特征融合到图1中;本脚本的完整代码地址见文末。使用dlib提取面部标志本脚本使用dlib的Pythonbindings来提取面部标志:dlib实现了VahidKazemi和JosephineSullivan所著论文《OneMillisecondFaceAlignmentwithanEnsembleofRegressionTree》一文中描述的算法。算法本身非常复杂,但是通过dlib的接口实现它非常简单:PREDICTOR_PATH="/home/matt/dlib-18.16/shape_predictor_68_face_landmarks.dat"detector=dlib.get_frontal_face_detector()predictor=dlib.shape_predictor(PREDICTOR_PATH)defget_landmarks(im):rects=detector(im,1)iflen(rects)>1:raiseTooManyFacesiflen(rects)==0:raiseNoFacesreturnnumpy.matrix([[p.x,p.y]forpinpredictor(im,rects[0]).parts()])get_landmarks()函数以numpy数组的形式接收图像,并返回一个68x2的元素矩阵。矩阵的每一行与输入图像中特定特征点的x,y坐标相对应。特征提取器(predictor)需要一个大概的边界框作为算法的输入。这将由传统的面部检测器(detector)提供。该面部检测器会返回一个矩形列表,其中每一个矩形与图像中的一张人脸相对应。生成predictor需要预先训练好的模型。该模型可在dlibsourceforgerepository下载。https://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2/download用普氏分析法(ProcrustesAnalysis)实现人脸对齐现在十大正规网投平台已经有两个面部标志矩阵,其中的每一行都含有某个面部特征的坐标(如第30行给出了鼻尖的坐标)。十大正规网投平台现在只要弄明白如何旋转、平移和缩放第一个向量的所有点,使其尽可能匹配第二个向量中的点。同理,同样的变换可用于将第二张图叠加在第一张图上。为使其更加数学化,十大正规网投平台设T,s和R,并求如下等式最小值:其中,R是一个2x2的正交矩阵,s是一个标量,T是一个二维向量,pi和qi是之前计算出的面部标志矩阵行标和列标。事实证明,这类问题用常规普氏分析法(OrdinaryProcrustesAnalysis)可以解决:deftransformation_from_points(points1,points2):points1=points1.astype(numpy.float64)points2=points2.astype(numpy.float64)c1=numpy.mean(points1,axis=0)c2=numpy.mean(points2,axis=0)points1-=c1points2-=c2s1=numpy.std(points1)s2=numpy.std(points2)points1/=s1points2/=s2U,S,Vt=numpy.linalg.svd(points1.T*points2)R=(U*Vt).Treturnnumpy.vstack([numpy.hstack(((s2/s1)*R,c2.T-(s2/s1)*R*c1.T)),numpy.matrix([0.,0.,1.])])十大正规网投平台逐步分析一下代码:将输入矩阵转换为浮点型。这也是后续步骤的必要条件。将每一个点集减去它的矩心。一旦为这两个新的点集找到了一个最佳的缩放和旋转方法,这两个矩心c1和c2就可以用来找到完整的解决方案。同样,将每一个点集除以它的标准偏差。这消除了缩放偏差。使用奇异值分解(singularvaluedecomposition)计算旋转部分。请参阅维基百科有关OrthogonalProcrustesProblem的文章,以了解它的具体工作原理。将整个变换过程以仿射变换矩阵形式返回。之后,返回结果可以插入OpenCV的cv2.warpAffine函数,将第二个图片映射到第一个图片上:defwarp_im(im,M,dshape):output_im=numpy.zeros(dshape,dtype=im.dtype)cv2.warpAffine(im,M[:2],(dshape[1],dshape[0]),dst=output_im,borderMode=cv2.BORDER_TRANSPARENT,flags=cv2.WARP_INVERSE_MAP)returnoutput_im校正第二张图片的颜色如果此时十大正规网投平台试图直接叠加面部特征,很快会发现一个问题:这样肯定是没法儿看的...两幅图像之间不同的肤色和光线造成了覆盖区域边缘的不连续。所以十大正规网投平台尝试修正它:COLOUR_CORRECT_BLUR_FRAC=0.6LEFT_EYE_POINTS=list(range(42,48))RIGHT_EYE_POINTS=list(range(36,42))defcorrect_colours(im1,im2,landmarks1):blur_amount=COLOUR_CORRECT_BLUR_FRAC*numpy.linalg.norm(numpy.mean(landmarks1[LEFT_EYE_POINTS],axis=0)-numpy.mean(landmarks1[RIGHT_EYE_POINTS],axis=0))blur_amount=int(blur_amount)ifblur_amount%2==0:blur_amount+=1im1_blur=cv2.GaussianBlur(im1,(blur_amount,blur_amount),0)im2_blur=cv2.GaussianBlur(im2,(blur_amount,blur_amount),0)#Avoiddivide-by-zeroerrors.im2_blur+=128*(im2_blur<=1.0)return(im2.astype(numpy.float64)*im1_blur.astype(numpy.float64)/im2_blur.astype(numpy.float64))现在效果怎么样?十大正规网投平台瞅瞅:这不是更奇怪了么...此函数试图改变图2的颜色来匹配图1,也就是用im2除以im2的高斯模糊,然后乘以im1的高斯模糊。在这里十大正规网投平台使用了颜色平衡(RGBscalingcolour-correction),但不是直接使用全图的常数比例因子,而是采用每个像素的局部比例因子。通过这种方法也只能在某种程度上修正两图间的光线差异。比如说,如果图1的光线来自某一边,但图2的光线非常均匀,校色后图2也会出现有一边暗一些的情况。也就是说,这是一个相当粗糙的解决方案,而且关键在于大小适当的高斯内核。如果太小,图2中会出现图1的面部特征。如果太大,内核会跑到被像素覆盖的面部区域之外,并变色。这里的内核大小为瞳距的0.6倍。将图2的特征融合到图1中用一个蒙版(mask)来选择图2和图1应被最终显示的部分:值为1(白色)的地方为图2应显示的区域,值为0(黑色)的地方为图1应显示的区域。值在0和1之间的地方为图1图2的混合区域。这是生成上述内容的代码:LEFT_EYE_POINTS=list(range(42,48))RIGHT_EYE_POINTS=list(range(36,42))LEFT_BROW_POINTS=list(range(22,27))RIGHT_BROW_POINTS=list(range(17,22))NOSE_POINTS=list(range(27,35))MOUTH_POINTS=list(range(48,61))OVERLAY_POINTS=[LEFT_EYE_POINTS+RIGHT_EYE_POINTS+LEFT_BROW_POINTS+RIGHT_BROW_POINTS,NOSE_POINTS+MOUTH_POINTS,]FEATHER_AMOUNT=11defdraw_convex_hull(im,points,color):points=cv2.convexHull(points)cv2.fillConvexPoly(im,points,color=color)defget_face_mask(im,landmarks):im=numpy.zeros(im.shape[:2],dtype=numpy.float64)forgroupinOVERLAY_POINTS:draw_convex_hull(im,landmarks[group],color=1)im=numpy.array([im,im,im]).transpose((1,2,0))im=(cv2.GaussianBlur(im,(FEATHER_AMOUNT,FEATHER_AMOUNT),0)>0)*1.0im=cv2.GaussianBlur(im,(FEATHER_AMOUNT,FEATHER_AMOUNT),0)returnimmask=get_face_mask(im2,landmarks2)warped_mask=warp_im(mask,M,im1.shape)combined_mask=numpy.max([get_face_mask(im1,landmarks1),warped_mask],axis=0)十大正规网投平台来分析一下:常规的get_face_mask()函数定义是:为一张图像和一个标志矩阵生成一个蒙版。蒙版会画出两个白色的凸多边形:一个是眼睛周围的区域,一个是鼻子和嘴部周围的区域。之后,蒙版的边缘区域向外羽化11个像素,这可以帮助消除剩下的不连续部分。为图1图2生成面部蒙版。使用与步骤2中的转换,可以使图2的蒙版转换至图1的坐标空间。之后,对所有元素取最大值操作,将这两个蒙版合二为一。这样做是为了保证图1的特征也能被覆盖的同时图2特征能显示出来。最后,将蒙版应用于最终图像:output_im=im1*(1.0-combined_mask)+warped_corrected_im2*combined_mask哈,换脸成功!附:本项目代码地址:https://github.com/matthewearl/faceswap/blob/master/faceswap.py参考资料:https://matthewearl.github.io/2015/07/28/switching-eds-with-python/
Python有哪些黑魔法
2019-11-06 17:50:19
- 上一条:上一篇:KTM摩托车为何可以连续拿到达喀尔拉力赛冠军
- 下一条:下一篇:保密协议是否有效