package com.objecteye.utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.objecteye.pojo.VehicleDetails; import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; @Component public class VehicleDetailsUtils { @Value("${snapshotPrefix}") private String snapshotPrefix; @Value("${picture.storePath}") private String storePath; private float sdkThreshold = 0.7F; //sdk的阈值 private float cpsbThreshold = 0.9F; //车牌识别的阈值 private String errorMsg = "识别异常"; /** * 将SDK中的数据封装成VehicleDetails类 */ public VehicleDetails sdkToVehicleDetails(JSONObject vehicleDetailsOne) { VehicleDetails vehicleDetails = new VehicleDetails(); //因为是用户上传过来的数据,所以图片路径为空 vehicleDetails.setPicurl(null); //图片路径 //获取车辆类型 JSONObject vehicle_recg_res = vehicleDetailsOne.getJSONObject("vehicle_recg_res"); Float name_score = vehicle_recg_res.getFloat("name_score"); String vehicle_type = errorMsg; String vehicle_recg_info = errorMsg; if (name_score > sdkThreshold) { name_score = (float) Math.round(name_score * 100) / 100; if (name_score > 1) { name_score = 1F; } vehicle_type = vehicle_recg_res.getString("vehicle_type"); String vehicle_brand = vehicle_recg_res.getString("vehicle_brand"); String vehicle_subbrand = vehicle_recg_res.getString("vehicle_subbrand"); String vehicle_issue_year = vehicle_recg_res.getString("vehicle_issue_year"); vehicle_recg_info = vehicle_brand + "-" + vehicle_subbrand + "-" + vehicle_issue_year; } vehicleDetails.setVehicle_recg_type(vehicle_type); //车辆类型 vehicleDetails.setVehicle_recg_brand(vehicle_recg_info); //车辆品牌型号(检测得到的车品牌、车子品牌、年份拼接而成) vehicleDetails.setVehicle_recg_name_score(name_score); //品牌可信度 //获取车身颜色 JSONObject vehicle_color_res = vehicleDetailsOne.getJSONObject("vehicle_color_res"); Float colorScore = vehicle_color_res.getFloat("score"); String vehicleColor = errorMsg; if (colorScore > sdkThreshold) { Integer vehicle_color_index = vehicle_color_res.getInteger("index"); vehicleColor = RelationMappingUtil.getVehicleColor(vehicle_color_index); } vehicleDetails.setVehicle_color(vehicleColor); //车颜色 //获取车辆号牌信息 JSONObject vehicle_plate_det_recg_res = vehicleDetailsOne.getJSONObject("vehicle_plate_det_recg_res"); Float numScore = vehicle_plate_det_recg_res.getFloat("numScore"); String vehiclePlateType = errorMsg; String plateHPHM = errorMsg; String ehicle_plate_status = "无号牌"; if (numScore > cpsbThreshold) { numScore = (float) Math.round(numScore * 100) / 100; if (numScore > 1) { numScore = 1F; } Integer type = vehicle_plate_det_recg_res.getInteger("type"); vehiclePlateType = RelationMappingUtil.getVehiclePlateType(type); JSONArray plateNumParams = vehicle_plate_det_recg_res.getJSONArray("plateNumParams"); int size = plateNumParams.size(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < size; i++) { JSONObject plateNumParamOne = plateNumParams.getJSONObject(i); Float maxprob = plateNumParamOne.getFloat("maxprob");//每位号牌可信度 String character = "*"; //每位号牌,默认为*,当置信度低于某个值时设置为* if (maxprob >= sdkThreshold) { character = plateNumParamOne.getString("character"); } character = plateNumParamOne.getString("character"); sb.append(character); } plateHPHM = sb.toString(); //判断车牌状态 if (plateHPHM.contains("*")) { ehicle_plate_status = "污损号牌"; } else { ehicle_plate_status = "完整号牌"; } } vehicleDetails.setVehicle_plate_type(vehiclePlateType); //车牌类型 vehicleDetails.setVehicle_plate_hphm(plateHPHM); //车牌号码 vehicleDetails.setVehicle_plate_detectScore(numScore); //车牌可信度 vehicleDetails.setVehicle_plate_status(ehicle_plate_status); //车牌状态 //获取特殊车辆类型:渣土车 危化品车 其他 JSONObject vehicle_special_res = vehicleDetailsOne.getJSONObject("vehicle_special_res"); Float specialScore = vehicle_special_res.getFloat("score"); String vehicleSpecialType = errorMsg; if (specialScore > sdkThreshold) { Integer vehicle_special_res_type = vehicle_special_res.getInteger("type"); vehicleSpecialType = RelationMappingUtil.getVehicleSpecialType(vehicle_special_res_type); } vehicleDetails.setSpecialty_vehicle_type(vehicleSpecialType); //特殊品类车辆类型 //因为是用户上传的图片所以没有抓拍时间,默认为当前时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String picTime = sdf.format(System.currentTimeMillis()); vehicleDetails.setPictime(picTime); //抓拍时间(2019-09-24 15:46:12) //获取设备名称(因为是用户上传的图片,所以设备名称默认为“用户手动上传”) String equipmentName = "无地点信息"; vehicleDetails.setEquipmentName(equipmentName);//设备名称 //获取经纬度(来源于用户上传的图片,所以不存在经纬度,默认为北京的经纬度) vehicleDetails.setLongitude("116.40"); //经度 vehicleDetails.setLatitude("39.90"); //纬度 //获取所有违法状态 JSONObject vehicle_illegal_det_res = vehicleDetailsOne.getJSONObject("vehicle_illegal_det_res"); String driverIllStatus = null; String copilotIllStatus = null; //主驾驶状态 JSONObject driver = vehicle_illegal_det_res.getJSONObject("driver"); StringBuilder driverIll = new StringBuilder(); JSONObject driverSmoke = driver.getJSONObject("smoke"); Float driverSmokeConfidence = driverSmoke.getFloat("confidence"); if (driverSmokeConfidence >= sdkThreshold) { String driverSmokeStatus = null; Integer status = driverSmoke.getInteger("status"); switch (status) { case 1000: driverSmokeStatus = "抽烟"; break; case 1001: driverSmokeStatus = "未抽烟"; break; default: driverSmokeStatus = "抽烟未知"; } driverIll.append(driverSmokeStatus).append("、"); } JSONObject driverBelt = driver.getJSONObject("belt"); Float driverBeltConfidence = driverBelt.getFloat("confidence"); if (driverBeltConfidence >= sdkThreshold) { String driverBeltStatus = null; Integer status = driverBelt.getInteger("status"); switch (status) { case 1000: driverBeltStatus = "未系安全带"; break; case 1001: driverBeltStatus = "系安全带"; break; default: driverBeltStatus = "安全带未知"; } driverIll.append(driverBeltStatus).append("、"); } JSONObject driverPhone = driver.getJSONObject("phone"); Float driverPhoneConfidence = driverPhone.getFloat("confidence"); if (driverPhoneConfidence >= sdkThreshold) { String driverPhoneStatus = null; Integer status = driverPhone.getInteger("status"); switch (status) { case 1000: driverPhoneStatus = "打电话"; break; case 1001: driverPhoneStatus = "未打电话"; break; default: driverPhoneStatus = "打电话未知"; } driverIll.append(driverPhoneStatus).append("、"); } JSONObject driverPerson = driver.getJSONObject("person"); Float driverPersonConfidence = driverPerson.getFloat("confidence"); if (driverPersonConfidence >= sdkThreshold) { String driverPersonStatus = null; Integer status = driverPerson.getInteger("status"); switch (status) { case 1000: driverPersonStatus = "无人"; break; case 1001: driverPersonStatus = "有人"; break; case 1003: driverPersonStatus = "无人"; break; case 1004: driverPersonStatus = "有人"; break; default: driverPersonStatus = "有无人未知"; } driverIll.append(driverPersonStatus).append("、"); } String driverIllInfo = driverIll.toString(); if (driverIllInfo.length() >= 1) { driverIllStatus = driverIllInfo.substring(0, driverIllInfo.length() - 1); } //副驾驶状态 JSONObject copilot = vehicle_illegal_det_res.getJSONObject("copilot"); StringBuilder copilotIll = new StringBuilder(); JSONObject copilotSmoke = copilot.getJSONObject("smoke"); Float copilotSmokeConfidence = copilotSmoke.getFloat("confidence"); if (copilotSmokeConfidence >= sdkThreshold) { String copilotSmokeStatus = null; Integer status = copilotSmoke.getInteger("status"); switch (status) { case 1000: copilotSmokeStatus = "抽烟"; break; case 1001: copilotSmokeStatus = "未抽烟"; break; default: copilotSmokeStatus = "抽烟未知"; } copilotIll.append(copilotSmokeStatus).append("、"); } JSONObject copilotBelt = copilot.getJSONObject("belt"); Float copilotBeltConfidence = copilotBelt.getFloat("confidence"); if (copilotBeltConfidence >= sdkThreshold) { String copilotBeltStatus = null; Integer status = copilotBelt.getInteger("status"); switch (status) { case 1000: copilotBeltStatus = "未系安全带"; break; case 1001: copilotBeltStatus = "系安全带"; break; default: copilotBeltStatus = "安全带未知"; } copilotIll.append(copilotBeltStatus).append("、"); } JSONObject copilotPhone = copilot.getJSONObject("phone"); Float copilotPhoneConfidence = copilotPhone.getFloat("confidence"); if (copilotPhoneConfidence >= sdkThreshold) { String copilotPhoneStatus = null; Integer status = copilotPhone.getInteger("status"); switch (status) { case 1000: copilotPhoneStatus = "打电话"; break; case 1001: copilotPhoneStatus = "未打电话"; break; default: copilotPhoneStatus = "打电话未知"; } copilotIll.append(copilotPhoneStatus).append("、"); } JSONObject copilotPerson = copilot.getJSONObject("person"); Float copilotPersonConfidence = copilotPerson.getFloat("confidence"); if (copilotPersonConfidence >= sdkThreshold) { String copilotPersonStatus = null; Integer status = copilotPerson.getInteger("status"); switch (status) { case 1000: copilotPersonStatus = "无人"; break; case 1001: copilotPersonStatus = "有人"; break; case 1003: copilotPersonStatus = "无人"; break; case 1004: copilotPersonStatus = "有人"; break; default: copilotPersonStatus = "有无人未知"; } copilotIll.append(copilotPersonStatus).append("、"); } String copilotIllInfo = copilotIll.toString(); if (copilotIllInfo.length() >= 1) { copilotIllStatus = copilotIllInfo.substring(0, copilotIllInfo.length() - 1); } //将主副驾驶状态填入 vehicleDetails.setVehicle_illegal_driver_status(driverIllStatus); //主驾驶状态 vehicleDetails.setVehicle_illegal_copilot_status(copilotIllStatus); //副驾驶状态 //获取车头照片 JSONObject vehicle_detect_res = vehicleDetailsOne.getJSONObject("vehicle_detect_res"); Float score = vehicle_detect_res.getFloat("score"); Integer ctCenter = 0; //车头中间线,用于分割主副驾位置 if (score >= 0.5) { JSONObject syRectParam = vehicle_detect_res.getJSONObject("syRectParam"); Integer width = syRectParam.getInteger("width"); Integer left = syRectParam.getInteger("left"); ctCenter = left + (width / 2); } //获取主副驾驶遮阳板、挂件、纸巾盒、转经筒 JSONObject vehicle_pendant_det_res = vehicleDetailsOne.getJSONObject("vehicle_pendant_det_res"); JSONArray vehiclePendantDetectInfoParams = vehicle_pendant_det_res.getJSONArray("vehiclePendantDetectInfoParams"); Integer count = vehicle_pendant_det_res.getInteger("count"); int njbNumber = 0; //年检标数量 String driverZYB = "无"; //主驾遮阳板 String copilotZYB = "无"; //副驾遮阳板 String gj = "无"; //挂件 String zjh = "无"; //纸巾盒 String zjt = "无"; //转经筒 for (int i = 0; i < count; i++) { JSONObject vehiclePendantJson = vehiclePendantDetectInfoParams.getJSONObject(i);//单个属性 Float confidence = vehiclePendantJson.getFloat("confidence"); if (confidence >= sdkThreshold) { Integer index = vehiclePendantJson.getInteger("index"); switch (index) { case 3: //判断主副驾驶 //获取遮阳板距离左边的距离 Integer zybLeft = vehiclePendantJson.getJSONObject("syRectParam").getInteger("left"); if (zybLeft > ctCenter) { //为副驾驶 copilotZYB = "有"; } else { driverZYB = "有"; } case 4: njbNumber++; case 5: gj = "有"; case 6: zjh = "有"; case 7: zjt = "有"; } } } vehicleDetails.setVehicle_driver_sunvisor(driverZYB); //主驾遮阳板 vehicleDetails.setVehicle_copilot_sunvisor(copilotZYB); //副驾遮阳板 vehicleDetails.setVehicle_annualInspectionStandard(String.valueOf(njbNumber)); //年检标 vehicleDetails.setVehicle_pendant(gj); //挂件 vehicleDetails.setVehicle_tissuebox(zjh); //纸巾盒 vehicleDetails.setVehicle_prayerwheel(zjt);//转经筒 //获取车辆特征值 JSONObject vehicle_fea_res = vehicleDetailsOne.getJSONObject("vehicle_fea_res"); JSONArray featureArr = vehicle_fea_res.getJSONArray("feature"); int size = featureArr.size(); Double[] featureNew = new Double[size]; for (int i = 0; i < size; i++) { featureNew[i] = featureArr.getDouble(i); } vehicleDetails.setVehicle_fea_res_feature(featureNew);//获取特征值 return vehicleDetails; } public ArrayList base64ToVehicleDetailsArr(JSONObject vehicleSDKJsonData) { ArrayList vehicleDetailsList = null; if (vehicleSDKJsonData.getString("msg").equals("success")) { //开始解析数据并封装成List JSONObject vehicleSDKResultJsonData = vehicleSDKJsonData.getJSONObject("result"); //查询本章图片检测到几个车 Integer count = vehicleSDKResultJsonData.getInteger("count"); JSONArray vehicleSDKinfoJson = vehicleSDKResultJsonData.getJSONArray("info"); vehicleDetailsList = new ArrayList<>(); for (int i = 0; i < count; i++) { //获取到单个的车辆数据 JSONObject vehicleDetailsOne = vehicleSDKinfoJson.getJSONObject(i); //调用通过vehicleSDKResultJsonData获取到单个车 VehicleDetails vehicleDetails = sdkToVehicleDetails(vehicleDetailsOne); vehicleDetailsList.add(vehicleDetails); } } return vehicleDetailsList; } /** * 从全景图中获取到抓拍车辆图的base64 */ public static String picToSnapshot(String url, int left, int top, int width, int height) { // String path = "http://192.168.10.153:8880/192.168.10.78_01_20190927092803811_FACE_ALARM104.jpg"; String snapshotBase64 = null; ByteArrayOutputStream baos = null; try { URL path = new URL(url); BufferedImage image = ImageIO.read(path); BufferedImage subimage = image.getSubimage(left, top, width, height); baos = new ByteArrayOutputStream(); ImageIO.write(subimage, "jpg", baos); byte[] bytes = baos.toByteArray(); String encode = Base64.encodeBase64String(bytes); snapshotBase64 = "data:image/jpeg;base64," + encode.replaceAll("\n", "").replaceAll("\r", ""); } catch (Exception e) { e.printStackTrace(); } finally { try { if (baos != null) { baos.close(); } } catch (IOException e) { e.printStackTrace(); } } return snapshotBase64; } /** * 通过全景图的URL截取到其中的快照图并放入到指定位置 */ String urlCutToImagePath(int index, String imgUrl, String subPath, Integer left, Integer top, Integer width, Integer height) { String snapshotPathNew = null; try { String substring = imgUrl.substring(imgUrl.lastIndexOf('/') + 1); BufferedImage read = ImageIO.read(new File(storePath + substring)); BufferedImage subimage = read.getSubimage(left, top, width, height); //获取到快照图的详细路径 String snapshotName = "SNAPSHOT_" + index + "_" + imgUrl.substring(imgUrl.lastIndexOf('/') + 1); String snapshotPath = subPath + snapshotName; File t = new File(snapshotPath); if (t.exists()) { t.delete(); } ImageIO.write(subimage, "jpg", t); return snapshotPrefix + snapshotName; } catch (IOException e) { e.printStackTrace(); } return snapshotPathNew; } }