java opencv bytearray转mat_使用 Java 实现人脸融合!

知道的越多,不知道的就越多,业余的像一棵小草!

编辑:业余草来源:https://www.xttblog.com/?p=5019

B站:业余草 人脸融合正在流行,毕竟这个社会一直都是看脸的时代! 今天周六,抽个时间给大家闲聊一下人脸融合技术。 说到这个技术,很多人可能很陌生,但是当提到 AI 人脸识别,AI 换脸,AI 算命,人脸美化等技术,相信都不陌生了。 况且这个技术目前 BAT 等巨头都有涉猎,国内的人工智能巨头新秀也不例外。可以说谁先占领了 AI,谁就在下一代浪潮中立身于不败之地。 说回技术本身,我也只是略懂皮毛。下面说一下,具体的实现思路。 93787e2601a5c2a34553f38acaab998b.png 如上图所示,在图片上的人脸中,找出这些特征点(一般,找 68、72 个就可以了)。 fcc79c3bad9e01a9ecd7b6853d9fbcce.png 如果脸型相同或相近,那么就可以换脸,进行融合了。 cc0a600b314cf379f4b8f412ae71f055.png bcf944e6c2f02e2edd6e7f8da7176835.png 说起来简单,但是实现起来就涉及到很多算法了。 a57858ea8fa2688466753ae60a9daadb.png 目前市面上多数的 APP 都是借助 Face++,BAT 等提供的 sdk api 实现的。这方面的 API 调用费用还挺贵的! 我的实现也很简单,借助开源类库,加上巨头提供的 API,基于 Java 实现人脸融合。 首先,利用 opencv 获得关键特征点。

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了您的问题。要使用Java OpenCV调用摄像头并动态识别人脸,您需要遵循以下步骤: 1. 安装OpenCV库 您需要在本地计算机上安装OpenCV库,以便能够在Java中调用OpenCV。您可以从OpenCV官方网站下载并安装OpenCV库。 2. 导入OpenCV库 在Java项目中,您需要导入OpenCV库。您可以使用Maven和Gradle等构建工具来导入OpenCV库。 3. 调用摄像头 您可以使用Java OpenCV中的VideoCapture类调用摄像头。以下是一个简单的示例代码: ``` import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.videoio.VideoCapture; public class CameraCapture { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); VideoCapture camera = new VideoCapture(0); if(!camera.isOpened()){ System.out.println("Error"); } else { Mat frame = new Mat(); while(true){ if (camera.read(frame)){ System.out.println("Frame Obtained"); System.out.println("Captured Frame Width " + frame.width() + " Height " + frame.height()); Core.flip(frame, frame, 1); break; } } } camera.release(); } } ``` 此代码段将获取从摄像头获取的帧并将其翻。 4. 识别人脸 要识别人脸,您可以使用Java OpenCV中的CascadeClassifier类。以下是一个简单的示例代码: ``` import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; import org.opencv.videoio.VideoCapture; public class FaceDetection { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); CascadeClassifier faceDetector = new CascadeClassifier("haarcascade_frontalface_alt.xml"); VideoCapture camera = new VideoCapture(0); Mat frame = new Mat(); while (true){ if (camera.read(frame)){ MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(frame, faceDetections); System.out.println(String.format("Detected %s faces", faceDetections.toArray().length)); for (Rect rect : faceDetections.toArray()){ Imgproc.rectangle(frame, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0)); } HighGui.imshow("Face Detection", frame); HighGui.waitKey(1); } } } } ``` 此代码段将检测从摄像头获取的帧中的面部,并将其框定。您需要下载名为“haarcascade_frontalface_alt.xml”的人脸检测器文件并将其放在代码中的相应位置。 希望这可以帮助您开始使用Java OpenCV调用摄像头并动态识别人脸

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值