百度AI人脸识别(面部器官分组及关键点连接)

效果图(在源图片基础上创建画板进行描绘)

在这里插入图片描述

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;
	}
	
}

赵日天第一次用这个编辑器写:哈哈哈哈!有很多话想说,又表达不出来,难受,看代码吧!再见;

哦,还有一句话要说:白嫖不好,谢谢;

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值