基于java 若依框架的项目要加个安全帽和工作服识别的demo。
1. 百度AI相关的配置
在application.yml文件中添加百度AI相关的配置,这些服务都可以免费用,企业用户可以有10QPS,在百度AI控制台创建应用即可获得。代码中还有车辆、人脸、敏感词、敏感图片等等的识别,可以忽略。
baidu:
img_in: 'D:/code/java/risun-smartsite/ruoyi-admin/camera_files_path/img_in/'
img_out: 'D:/code/java/risun-smartsite/ruoyi-admin/camera_files_path/img_out/'
body_attr:
URL:
APP_ID:
API_KEY:
SECRET_KEY:
2. java依赖库
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.15.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
3. java工具类
java工具类下载地址https://download.csdn.net/download/zj850324/86512278
4. 人体属性识别
package com.ruoyi.ai.service;
import com.ruoyi.ai.tools.AuthService;
import com.ruoyi.ai.tools.GlobalParameters;
import com.ruoyi.ai.tools.HttpUtil;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author created by Jerry
* @date 2022年9月2日---下午3:28:15
* @problem
* @answer
* @action
*/
@Component
public class BodyAttr {
@Autowired
AuthService m_AuthService;
@Autowired
GlobalParameters m_GlobalParameters;
public String distinguish(String imgParam) throws Exception{
String result = "";
imgParam = URLEncoder.encode(imgParam, "UTF-8");
String param = "image=" + imgParam;
String accessToken = m_AuthService.getG_BodyAttr();
result = HttpUtil.post(m_GlobalParameters.getM_body_attr_url(), accessToken, param);
return result;
}
}
5. java定时任务
暂时分离网络摄像头相关的部分,用静态图代替。摄像头部分可参考我的前两篇。
package com.ruoyi.quartz.task;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ruoyi.ai.service.BodyAttr;
import com.ruoyi.ai.tools.FileUtilEx;
import com.ruoyi.ai.tools.ImageTools;
import com.ruoyi.camera.domain.JCameraInfo;
import com.ruoyi.camera.domain.JCameraWarning;
import com.ruoyi.camera.service.IJCameraInfoService;
import com.ruoyi.camera.service.IJCameraWarningService;
import com.ruoyi.common.utils.uuid.UUID;
import cn.hutool.core.io.FileUtil;
import java.io.*;
import java.text.SimpleDateFormat;
/**
* 智能识别定时任务
*
* @author ruoyi
*/
@Component("ryDistinguishTask")
public class RyDistinguishTask {
@Autowired
private IJCameraInfoService jCameraInfoService;
@Autowired
private IJCameraWarningService jCameraWarningService;
@Autowired
private BodyAttr m_BodyAttr;
// 摄像头截图根目录
@Value("${baidu.img_in}")
private String img_in;
@Value("${baidu.img_out}")
private String img_out;
private JCameraInfo jCameraInfo = new JCameraInfo();
public void action() {
jCameraInfo.setCiType2("智能识别");
List<JCameraInfo> list = jCameraInfoService.selectJCameraInfoList(jCameraInfo);
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
JCameraInfo jci = (JCameraInfo) iterator.next();
try {
getBodyAttr(jci);
} catch (Exception e) {
// 忽略
e.printStackTrace();
}
}
}
/** 是否入库 */
private boolean isSave(JsonObject res) throws Exception {
boolean isSave = false;
String personNum=res.get("person_num").toString();
if(personNum.equals("0")) {
return isSave;
}
JsonArray person_info = res.getAsJsonArray("person_info");
for (int i = 0; i < person_info.size(); i++) {
JsonObject jo = person_info.get(i).getAsJsonObject().get("attributes").getAsJsonObject();
String hat =jo.get("headwear").getAsJsonObject().get("name").toString();
String is_human = jo.get("is_human").getAsJsonObject().get("name").toString();
if(is_human.equals("\"正常人体\"") && !hat.equals("\"安全帽\"")) {
isSave = true;
break;
}
}
return isSave;
}
/** 识别 */
private void getBodyAttr(JCameraInfo jci) throws Exception {
String in = img_in + jci.getCiId() + "/0.jpg";
// 网络图片转BASE64
// String strNetImageToBase64 = ImageTools.netImageToBase64(ImagePath);
// 本地图片转BASE64
String strNetImageToBase64 = ImageTools.imageToBase64(in);
String res_text = m_BodyAttr.distinguish(strNetImageToBase64);
JsonObject res = new JsonParser().parse(res_text).getAsJsonObject();
if(res.get("error_code") != null) {
return;
}
if (isSave(res)){
Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String dir = jci.getCiId() + "/" + df.format(day) + "/";
String imgPath =UUID.randomUUID() + ".jpg";
// 存图像
FileUtilEx.createDir(img_out + dir);
FileUtil.copyFilesFromDir(new File(in), new File( img_out + dir + imgPath), false);
// 存数据
JCameraWarning jCameraWarning = new JCameraWarning();
jCameraWarning.setCiId(jci.getCiId());
jCameraWarning.setCiV1(res_text);
jCameraWarning.setCwImage(dir + imgPath);
jCameraWarning.setCwStatus("未处理");
jCameraWarning.setCwType("综合");
jCameraWarningService.insertJCameraWarning(jCameraWarning);
}
}
}
6. VUE显示识别效果,完整代码太啰嗦我贴一部分
<el-row class="box-pin">
<el-col :span="24">
<canvas id="mycanvas" width="1100px" height="500px"></canvas>
</el-col>
</el-row>
<style lang="less" scoped>
#mycanvas {
border: 1px solid rgb(199, 198, 198);
}
</style>
/** 处理任务 */
handleDetails(row) {
this.reset();
const cwId = row.cwId || this.ids
getWarning(cwId).then(response => {
this.form = response.data;
this.form.cwUid = this.user_info.userId;
this.form.cwMethod = this.form.cwMethod.split(",");
this.form.cwStatus = "已处理";
this.showProcess = true;
this.$nextTick(() => {
this.doDraw(this.form);
});
});
},
/** 画图、矩形 */
doDraw(cw) {
let imageUrl = "https://p2.itc.cn/q_70/images03/20210812/4b91d076d1cf4765a10664627e468991.jpeg";
// 获取canvas
var canvas = document.getElementById("mycanvas")
// 由于弹窗,确保已获取到
var a = setInterval(() => {
// 重复获取
canvas = document.getElementById("mycanvas")
if (!canvas) {
return false
} else {
clearInterval(a)
// 可以理解为一个画笔,可画路径、矩形、文字、图像
var context = canvas.getContext('2d')
var img = new Image()
img.src = imageUrl
// 加载图片
img.onload = function () {
if (img.complete) {
let wz = canvas.width / img.width;
let hz = canvas.height / img.height;
let zoom = wz < hz ? wz : hz;
let offsetX = canvas.width - img.width * zoom;
let offsetY = canvas.height - img.height * zoom;
offsetX = offsetX / 2;
offsetY = offsetY / 2;
// 根据图像重新设定了canvas的长宽
// canvas.setAttribute("width",img.width);
// canvas.setAttribute("height",img.height);
// 绘制图片
context.drawImage(img, offsetX, offsetY, img.width * zoom, img.height * zoom);
this.aires = JSON.parse(cw.ciV1);
for (let index = 0; index < this.aires.person_info.length; index++) {
const element = this.aires.person_info[index];
if (element.attributes.headwear.name == "安全帽") {
context.strokeStyle = "#00FF00";
}
else {
context.strokeStyle = "#FF0000";
}
context.lineWidth = 3;
context.strokeRect(element.location.left, element.location.top, element.location.width, element.location.height);
context.font = "16px Arial bolder";
context.fillStyle = "#FFFF00";
if(element.attributes.headwear.name != "不确定")
{
context.fillText(element.attributes.headwear.name,element.location.left,element.location.top + 30);
}
if(element.attributes.face_mask.name != "不确定")
{
context.fillText(element.attributes.face_mask.name,element.location.left,element.location.top + 60);
}
if(element.attributes.upper_wear.name != "不确定")
{
context.fillText(element.attributes.upper_color.name + element.attributes.upper_wear.name,element.location.left,element.location.top + 90);
}
if(element.attributes.lower_wear.name != "不确定")
{
context.fillText(element.attributes.lower_color.name + element.attributes.lower_wear.name,element.location.left,element.location.top + 120);
}
}
}
}
}
}, 1);
},