上一篇文章介绍了动态修改3D人脸模型的顶点要注意的问题。
结合人脸检测技术,根据人脸关键点实时修改顶点坐标,就能让3D人脸模型跟随自己的面部变化了。
这时候如果想让3D人脸模型换一张脸呢?
其中一种方式就是根据旧的贴图,用Photoshop调整新的贴图的五官位置:

讯享网
给人脸模型替换新的贴图后,实现的效果如下:

贴图坐标的定义
···省略 f 23/1/1 21/2/1 31/3/1 f 23/1/2 24/4/2 21/2/2 f 24/4/3 25/5/3 21/2/3 f 25/5/4 26/6/4 21/2/4 f 21/2/5 26/6/5 6/7/5 ···省略
讯享网
上一篇文章有提到过,f后面每行有三组数字。每组的第一个数字是顶点坐标的序号,第二个数字是贴图坐标的序号。
之前介绍如何修改人脸模型左眼角的顶点坐标时,已经知道左眼角的顶点坐标序号是21。
从上面的几组数字中,找到以21为开头的一组,看到21斜杠后面是2。
意思就是序号为21的顶点坐标,对应序号为2的贴图坐标。
再找到以”vt”开头的行:
讯享网···省略 vt 0.2147 0.6968 vt 0.3233 0.6276 vt 0.3213 0.7244 vt 0.2208 0.5305 vt 0.2612 0.3763 ···省略

vt 0.3233 0.6276
用Photoshop打开这张贴图,拉出标尺看就明白了:

Rajawali中替换模型贴图
内置于APP中的Obj模型文件放在res/raw目录中,其贴图素材放在res/drawable-nodpi目录中。
由于我们的“换脸”方案需要修改Obj模型文件的内容,为便于处理,将Obj模型文件复制到SD卡中。
加载SD卡中的模型文件,与加载内置的模型文件有些区别,代码如下:
讯享网protected void initScene() { try { // 加载SD卡中的人脸模型 // objPath是模型文件的路径 String objPath = "xxx"; LoaderOBJ parser = new LoaderOBJ(this, objPath); parser.parse(); Object3D faceModel = parser.getParsedObject(); // 添加模型到场景中 getCurrentScene().addChild(faceModel); } catch (ParsingException e) { e.printStackTrace(); } }
public ILoader parse() throws ParsingException { if (mFile == null && mFileOnSDCard != null) mFile = new File(Environment.getExternalStorageDirectory(), mFileOnSDCard); if (mFile != null && RajLog.isDebugEnabled()) RajLog.d("Parsing: " + mFile.getAbsolutePath()); return this; }
接下来就是替换贴图,修改上面的代码:
讯享网// ...省略 Object3D faceModel = parser.getParsedObject(); ATexture texture = faceModel.getMaterial().getTextureList().get(0); // 先移除旧的贴图 faceModel.getMaterial().removeTexture(texture); // 读取新的贴图素材 String newTexture = "xxx"; Bitmap bitmap = BitmapFactory.decodeFile(newTexture); // 替换新的贴图 faceModel.getMaterial().addTexture(new Texture("canvas", bitmap));
替换新贴图之前,还可以对bitmap做一些处理,比如调整人脸的肤色,让“换脸”效果更自然:

左边是调整前,右边是调整后,目前调肤色效果还不太理想,暂时就不介绍了。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/62903.html