知道的越多,不知道的就越多,业余的像一棵小草!
编辑:业余草来源:https://www.xttblog.com/?p=5019
B站:业余草
人脸融合正在流行,毕竟这个社会一直都是看脸的时代!
今天周六,抽个时间给大家闲聊一下人脸融合技术。
说到这个技术,很多人可能很陌生,但是当提到 AI 人脸识别,AI 换脸,AI 算命,人脸美化等技术,相信都不陌生了。
况且这个技术目前 BAT 等巨头都有涉猎,国内的人工智能巨头新秀也不例外。可以说谁先占领了 AI,谁就在下一代浪潮中立身于不败之地。
说回技术本身,我也只是略懂皮毛。下面说一下,具体的实现思路。
如上图所示,在图片上的人脸中,找出这些特征点(一般,找 68、72 个就可以了)。
如果脸型相同或相近,那么就可以换脸,进行融合了。
说起来简单,但是实现起来就涉及到很多算法了。
目前市面上多数的 APP 都是借助 Face++,BAT 等提供的 sdk api 实现的。这方面的 API 调用费用还挺贵的!
我的实现也很简单,借助开源类库,加上巨头提供的 API,基于 Java 实现人脸融合。
首先,利用 opencv 获得关键特征点。
publicstaticvoidmain(String[]args)throwsFileNotFoundException{
Stringpath1=ResourceUtils.getFile("classpath:img/3m.jpg").getAbsolutePath();
Stringpath2=ResourceUtils.getFile("classpath:img/2m.jpg").getAbsolutePath();
StringsavePath="/User/业余草/face";//图片存放位置
// 参数说明
// type :opencv和baidu 两种获取人脸标记的位置点
// true 使用全部点位进行分割,false使用外部轮廓的点位进行融合
OpenCVFaceSwap.faceMerge(path1,path2,savePath,"opencv",true);
}
然后,进行第三方 API 调用。
//人脸检测
ImageInfoimageInfo=getRGBData(path1);
ListfaceInfoList=newArrayList();
errorCode=faceEngine.detectFaces(imageInfo.getImageData(),imageInfo.getWidth(),imageInfo.getHeight(),imageInfo.getImageFormat(),faceInfoList);
System.out.println(faceInfoList);
//特征提取
FaceFeaturefaceFeature=newFaceFeature();
errorCode=faceEngine.extractFaceFeature(imageInfo.getImageData(),imageInfo.getWidth(),imageInfo.getHeight(),imageInfo.getImageFormat(),faceInfoList.get(0),faceFeature);
System.out.println("特征值大小:"+faceFeature.getFeatureData().length);
//人脸检测2
ImageInfoimageInfo2=getRGBData(path2);
ListfaceInfoList2=newArrayList();
errorCode=faceEngine.detectFaces(imageInfo2.getImageData(),imageInfo2.getWidth(),imageInfo2.getHeight(),imageInfo.getImageFormat(),faceInfoList2);
System.out.println(faceInfoList);
//特征提取2
FaceFeaturefaceFeature2=newFaceFeature();
errorCode=faceEngine.extractFaceFeature(imageInfo2.getImageData(),imageInfo2.getWidth(),imageInfo2.getHeight(),imageInfo.getImageFormat(),faceInfoList2.get(0),faceFeature2);
System.out.println("特征值大小:"+faceFeature.getFeatureData().length);
//特征比对
FaceFeaturetargetFaceFeature=newFaceFeature();
targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
FaceFeaturesourceFaceFeature=newFaceFeature();
sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
FaceSimilarfaceSimilar=newFaceSimilar();
errorCode=faceEngine.compareFaceFeature(targetFaceFeature,sourceFaceFeature,faceSimilar);
System.out.println("相似度:"+faceSimilar.getScore());
//引擎卸载
errorCode=faceEngine.unInit();
上面就是比较核心的代码。
publicstaticMatflow(Matmat){
// 灰度
mat=OpencvUtil.gray(mat);
// 二值化 此处绝定图片的清晰度
mat=OpencvUtil.binary(mat);
// 腐蚀 去除背景图片
mat=OpencvUtil.erode(mat,1);
returnmat;
}
/**
* 灰化处理
*
* @return
*/
publicstaticMatgray(Matmat){
Matgray=newMat();
opencv_imgproc.cvtColor(mat,gray,opencv_imgproc.COLOR_BGR2GRAY,1);
returngray;
}
/**
* 增强对比
* @param mat
* @return
*/
publicstaticMatsplitBGR(Matmat){
MatVectorsplitBGR=newMatVector();
opencv_core.split(mat,splitBGR);
for(inti=0;i
opencv_imgproc.equalizeHist(splitBGR.get(i),splitBGR.get(i));
}
opencv_core.merge(splitBGR,mat);
returnmat;
}
另外还涉及到一些图片的特殊处理,利用的也是 Opencv。
说白了,我不具有核心技术,我就是一个 API 调用工程师。核心算法我一概不懂,专业造轮子。
做的牛逼一点的,可以从视频中提取图片,再进行融合。
感兴趣的,可以尝试自己查查资料,借助各云服务厂商的免费 API 调用额度,做一款让自己“吃到饱”的应用!
本文中的源码,只是一个简单的 demo,有兴趣的可以加我 WX:codedq,拿去接着研究研究!