1、核心工具类
public static List<FaceSuccessInfo> faceChage(Mat mat,String fileUrl) {
List<FaceSuccessInfo> list = new ArrayList<FaceSuccessInfo>();
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
ImageInfo imageInfo = ImageFactory.bufferedImage2GrayImageInfo(Mat2BufImg(mat,".png"));
//人脸检测
int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),imageInfo.getImageFormat(), faceInfoList);
if(faceInfoList.size() <= 0)
return null;
//特征提取2
FaceFeature faceFeature = new FaceFeature();
//循环遍历识别到的人脸
for (int i = 0; i<faceInfoList.size(); i++) {
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(i), faceFeature);
FaceFeature targetFaceFeature = new FaceFeature();
targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
boolean faceIs = false;
//得到复制好了的常量变量
for (int j = 0; j < FaceDB.facedb.size(); j++) {
FaceSimilar faceSimilar = new FaceSimilar();
errorCode = faceEngine.compareFaceFeature(targetFaceFeature, FaceDB.facedb.get(j).getFaceFeature(), faceSimilar);
//小数变百分比
int number = Integer.parseInt(new DecimalFormat("0").format(faceSimilar.getScore()*100));
if(number > FACE_SIMILARITY) {
faceIs = true;
//绘制方框
/*Imgproc.rectangle(mat,
new Point(faceInfoList.get(i).getRect().getLeft(),faceInfoList.get(i).getRect().getTop()),
new Point(faceInfoList.get(i).getRect().getRight(),faceInfoList.get(i).getRect().getBottom()),
contrastColor, 2);*/
//人脸图不能大于背景图
int x = faceInfoList.get(i).getRect().getLeft();
if(x < 0)
x = x * -1;
int y = faceInfoList.get(i).getRect().getTop();
if(y < 0)
y = y * -1;
int width = faceInfoList.get(i).getRect().getRight() - faceInfoList.get(i).getRect().getLeft();
if(width < 0)
width = width * -1;
int height = faceInfoList.get(i).getRect().getBottom() - faceInfoList.get(i).getRect().getTop();
if(height < 0)
height = height * -1;
//判断截图不能超过图片大小
if(mat.cols()<(x+width))
width = mat.cols() - x;
if(mat.rows() <(y+height))
height = mat.rows() - y;
//读取头
Mat srcImageMat = Imgcodecs.imread(fileUrl);
Mat msk1 = Imgcodecs.imread(fileUrl,0);
Mat msk = msk1.clone();
//反色
Core.bitwise_not(msk1,msk);
Mat newSrcImageMat = new Mat();
Imgproc.resize(srcImageMat, newSrcImageMat, new Size(width, height));
Mat newMsk = new Mat();
Imgproc.resize(msk, newMsk, new Size(width, height));
//感兴趣的区域
Mat imageROI = new Mat(mat,new Rect(x, y, width, height));
newSrcImageMat.copyTo(imageROI,newMsk);
//newSrcImageMat.copyTo(imageROI);
//System.out.println("mat1 = " + newMsk.channels());
//System.out.println("mat = " + mat.channels());
//添加返回数据
FaceSuccessInfo fsi = new FaceSuccessInfo();
fsi.setFaceId(FaceDB.facedb.get(j).getFaceId());
fsi.setFaceSimilarity(number);
fsi.setName(FaceDB.facedb.get(j).getName());
list.add(fsi);
break;
}
}
}
return list;
}
开发过程中,中间有个反色的操作卡了我很久,我一直以为是RGB三通道而RGBA是四通道,通道引起的PNG不透明。改了通道还是不透明,最后把图像通道分离了再和并还是白色。还好在看C++的一篇文章的时候来了灵感。
int main(){
Mat image = imread("1.jpg");
Mat logo = imread("2.png");
Mat mask = imread("2.png",0); //注意要是灰度图才行
threshold(mask,mask,254,255,CV_THRESH_BINARY);
Mat mask1 = 255 - mask; //掩模反色
//imshow("img",mask1);
Mat imageROI;
imageROI = image(Rect(480,320,logo.cols,logo.rows));
logo.copyTo(imageROI,mask1);
namedWindow("result");
imshow("result",image);
imwrite("result.jpg",image);
waitKey();
return 0;
}
掩模反色 ,在java中是
//反色
Core.bitwise_not(msk1,msk);
2、最后再来看看初步的实现效果吧
人脸贴合的算法后面还要改,现在只是一个Demo,不过用来做鬼畜视频效果够了,哈哈。
3、视频
原视频
换脸后
最后修改于 2021-01-27 22:03:09
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

