效果图(在源图片基础上创建画板进行描绘)
1.获取人脸检测数据
具体的不做代码分享了: 百度官方API地址
2.面部器官数据分组
//数据字段示例(数字代表在该器官组中的序列)
/**
* @func 人脸器官分组
* @author zxt
* @param landmark150
* @return Map<String,Integer> : key = 位置名,value = 连接个数
*/
public static Map<String,Integer> group(JSONObject landmark150) {
Map<String,Integer> groupMap = new HashMap<>();
Set<String> SetArray = landmark150.keySet();
for (String key : SetArray) {
//以下划线分组
String[] arr = key.split("_");
//查询该字段中是否存在数字(是否存在多个序列字段)
Pattern pat = Pattern.compile("\\d");
String strrr = arr[arr.length - 1].substring(0,1);
Matcher mat = pat.matcher(strrr);
Integer count = 1;
if (mat.matches()) {
key = key.replace("_"+arr[arr.length - 1], "");
}
//记录该器官组名的连接总数到分组Map
count = groupMap.get(key);
count = count == null ? 1 : count + 1;
groupMap.put(key, count);
}
return groupMap;
}
3.添加对象
/**
* @func 人脸位置坐标
* @author zxt
* @date 2020年01月11日
*/
public class FaceLandmark_Location {
/**
* x 坐标位置
*/
private double x;
/**
* y 坐标位置
*/
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "FaceDetectLandmark_Location [x=" + x + ", y=" + y + "]";
}
}
4.获取图片源比例
/**
* 获取图片宽度和高度
*
* @param 图片路径
* @return 返回图片的宽度
*/
public static int[] getImgWidthHeight(InputStream is) {
BufferedImage src = null;
int result[] = { 0, 0 };
try {
// 获得文件输入流
// 从流里将图片写入缓冲图片区
src = ImageIO.read(is);
result[0] =src.getWidth(null); // 得到源图片宽
result[1] =src.getHeight(null);// 得到源图片高
is.close(); //关闭输入流
} catch (Exception ef) {
ef.printStackTrace();
}
return result;
}
5.创建画板进行连接及生产源比例图片文件
参数获取路径:
创建画板获取图片:
package com.zxkj.face.detect.controller;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zxkj.ad.uplodStage.controller.FastDFSClient;
import com.zxkj.face.compare.controller.FaceCompareController;
import com.zxkj.warning.base.util.baiduAI.GsonUtils;
import com.zxkj.warning.base.util.baiduAI.entity.FaceLocationEntity;
import com.zxkj.warning.base.util.baiduAI.faceLandmark.FaceLandmark_Location;
import com.zxkj.warning.imgUpload.Imgys;
public class FaceDetectMark {
public final static String apend = "_";
/**
* @func 人脸关键点位置标记
* @author zxt
* @date 2020年01月11日
* @param request
* @param jsonArray : 人脸关键点标记位置
* @param imgUrl : 图片地址(无前缀)
* @return 新的文件路径
*/
public static String markFace(HttpServletRequest request,JSONArray jsonArray,String imgUrl) {
//读取图片文件,得到BufferedImage对象
BufferedImage bimg= null;
InputStream inp = FastDFSClient.downloadFile(imgUrl);
String fileId = null;
try {
//读取原图片
if(inp != null){
bimg = ImageIO.read(inp);
//创建画笔
Graphics2D mark_rag = bimg.createGraphics();
//设置红色
mark_rag.setColor(Color.yellow);
//设置粗细
mark_rag.setStroke(new BasicStroke(1.90f));
//创建画笔
Graphics2D joint_rag = bimg.createGraphics();
//设置红色
joint_rag.setColor(Color.yellow);
//设置粗细
joint_rag.setStroke(new BasicStroke(0.6f));
for (Object object : jsonArray) {
JSONObject face_list_0 = GsonUtils.fromJson(object.toString(),JSONObject.class);
JSONObject landmark150 = GsonUtils.fromJson(face_list_0.getString("landmark150"),JSONObject.class);
Map<String, Integer> groupMap = group(landmark150);
Set<String> groupSetArray = groupMap.keySet();
for (String key : groupSetArray) {
int getCount = groupMap.get(key);
String nowKey = key;
if (getCount > 1) {
nowKey = key + apend + 1;
}
FaceLandmark_Location faceLocation= GsonUtils.fromJson(landmark150.getString(nowKey),FaceLandmark_Location.class);
int x_1 = (int) faceLocation.getX();
int y_1 = (int) faceLocation.getY();
//标记关键点
mark_rag.drawLine(x_1,y_1,x_1,y_1);
System.err.println(x_1+" "+y_1+" "+x_1+" "+y_1+" key1 = "+key);
int count = groupMap.get(key);
if (count > 1) {
for (int i = 2; i <= count; i++) {
String next_key = key + apend + i;
FaceLandmark_Location nowFaceLocation= GsonUtils.fromJson(landmark150.getString(next_key),FaceLandmark_Location.class);
int x_2 = (int) nowFaceLocation.getX();
int y_2 = (int) nowFaceLocation.getY();
//标记关键点
mark_rag.drawLine(x_2,y_2,x_2,y_2);
//人脸关键点连接
joint_rag.drawLine(x_1,y_1,x_2,y_2);
System.err.println(x_1+" "+y_1+" "+x_2+" "+y_2+" key1 = "+key+" == key2:" +next_key);
//重置连接点到当前连接点
x_1 = (int) nowFaceLocation.getX();
y_1 = (int) nowFaceLocation.getY();
}
}
}
}
//生效
mark_rag.dispose();
//生效
joint_rag.dispose();
//创建图片
String locaPath = request.getSession().getServletContext().getRealPath("tmp");
String locaUrl = locaPath + File.separator + "456.jpg";
File file = new File(locaUrl);
//保存新图片
ImageIO.write(bimg, "PNG",file);
Imgys imgCom = new Imgys(file);
//源比例压缩
int[] a = FaceCompareController.getImgWidthHeight(new FileInputStream(file));
imgCom.resize(request,a[0], a[1]);
// 上传
fileId = FastDFSClient.uploadFile(file,file.getName());
System.err.println("人脸位置标记图片:" +fileId);
inp.close();
}else{
return null;
}
} catch (IOException e) {
e.printStackTrace(System.err);
}finally {
if (inp != null) {
try {
inp.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
return fileId;
}
/**
* @func 人脸器官分组
* @author zxt
* @param landmark150
* @return Map<String,Integer> : key = 位置名,value = 连接个数
*/
public static Map<String,Integer> group(JSONObject landmark150) {
Map<String,Integer> groupMap = new HashMap<>();
Set<String> SetArray = landmark150.keySet();
for (String key : SetArray) {
String[] arr = key.split("_");
Pattern pat = Pattern.compile("\\d");
String strrr = arr[arr.length - 1].substring(0,1);
Matcher mat = pat.matcher(strrr);
Integer count = 1;
if (mat.matches()) {
key = key.replace("_"+arr[arr.length - 1], "");
}
count = groupMap.get(key);
count = count == null ? 1 : count + 1;
groupMap.put(key, count);
}
return groupMap;
}
}