知道的越多,不知道的就越多,业余的像一棵小草!
编辑:业余草来源:https://www.xttblog.com/?p=5019
B站:业余草 人脸融合正在流行,毕竟这个社会一直都是看脸的时代! 今天周六,抽个时间给大家闲聊一下人脸融合技术。 说到这个技术,很多人可能很陌生,但是当提到 AI 人脸识别,AI 换脸,AI 算命,人脸美化等技术,相信都不陌生了。 况且这个技术目前 BAT 等巨头都有涉猎,国内的人工智能巨头新秀也不例外。可以说谁先占领了 AI,谁就在下一代浪潮中立身于不败之地。 说回技术本身,我也只是略懂皮毛。下面说一下,具体的实现思路。![93787e2601a5c2a34553f38acaab998b.png](https://img-blog.csdnimg.cn/img_convert/93787e2601a5c2a34553f38acaab998b.png)
![fcc79c3bad9e01a9ecd7b6853d9fbcce.png](https://img-blog.csdnimg.cn/img_convert/fcc79c3bad9e01a9ecd7b6853d9fbcce.png)
![cc0a600b314cf379f4b8f412ae71f055.png](https://img-blog.csdnimg.cn/img_convert/cc0a600b314cf379f4b8f412ae71f055.png)
![bcf944e6c2f02e2edd6e7f8da7176835.png](https://img-blog.csdnimg.cn/img_convert/bcf944e6c2f02e2edd6e7f8da7176835.png)
![a57858ea8fa2688466753ae60a9daadb.png](https://img-blog.csdnimg.cn/img_convert/a57858ea8fa2688466753ae60a9daadb.png)
public static void main(String[] args) throws FileNotFoundException {
String path1 = ResourceUtils.getFile("classpath:img/3m.jpg").getAbsolutePath();
String path2 = ResourceUtils.getFile("classpath:img/2m.jpg").getAbsolutePath();
String savePath = "/User/业余草/face";//图片存放位置
// 参数说明
// type :opencv和baidu 两种获取人脸标记的位置点
// true 使用全部点位进行分割,false使用外部轮廓的点位进行融合
OpenCVFaceSwap.faceMerge(path1,path2,savePath,"opencv",true);
}
然后,进行第三方 API 调用。
//人脸检测
ImageInfo imageInfo = getRGBData(path1);
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
System.out.println(faceInfoList);
//特征提取
FaceFeature faceFeature = new FaceFeature();
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
System.out.println("特征值大小:" + faceFeature.getFeatureData().length);
//人脸检测2
ImageInfo imageInfo2 = getRGBData(path2);
List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),imageInfo.getImageFormat(), faceInfoList2);
System.out.println(faceInfoList);
//特征提取2
FaceFeature faceFeature2 = new FaceFeature();
errorCode = faceEngine.extractFaceFeature(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo.getImageFormat(), faceInfoList2.get(0), faceFeature2);
System.out.println("特征值大小:" + faceFeature.getFeatureData().length);
//特征比对
FaceFeature targetFaceFeature = new FaceFeature();
targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
FaceFeature sourceFaceFeature = new FaceFeature();
sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
FaceSimilar faceSimilar = new FaceSimilar();
errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
System.out.println("相似度:" + faceSimilar.getScore());
//引擎卸载
errorCode = faceEngine.unInit();
上面就是比较核心的代码。
public static Mat flow(Mat mat) {
// 灰度
mat = OpencvUtil.gray(mat);
// 二值化 此处绝定图片的清晰度
mat = OpencvUtil.binary(mat);
// 腐蚀 去除背景图片
mat = OpencvUtil.erode(mat, 1);
return mat;
}
/**
* 灰化处理
*
* @return
*/
public static Mat gray(Mat mat) {
Mat gray = new Mat();
opencv_imgproc.cvtColor(mat, gray, opencv_imgproc.COLOR_BGR2GRAY, 1);
return gray;
}
/**
* 增强对比
* @param mat
* @return
*/
public static Mat splitBGR(Mat mat) {
MatVector splitBGR = new MatVector();
opencv_core.split(mat, splitBGR);
for (int i = 0; i<mat.channels(); i++){
opencv_imgproc.equalizeHist(splitBGR.get(i), splitBGR.get(i));
}
opencv_core.merge(splitBGR, mat);
return mat;
}
另外还涉及到一些图片的特殊处理,利用的也是 Opencv。
说白了,我不具有核心技术,我就是一个 API 调用工程师。核心算法我一概不懂,专业造轮子。
做的牛逼一点的,可以从视频中提取图片,再进行融合。
感兴趣的,可以尝试自己查查资料,借助各云服务厂商的免费 API 调用额度,做一款让自己“吃到饱”的应用!
本文中的源码,只是一个简单的 demo,有兴趣的可以加我 WX:codedq,拿去接着研究研究!
![302a3b69bf78b815ce6e512b74014b92.png](https://img-blog.csdnimg.cn/img_convert/302a3b69bf78b815ce6e512b74014b92.png)