Browse Source

无人机红外图片温度分析标注

master
wangxun 8 months ago
parent
commit
1befc79195
3 changed files with 162 additions and 89 deletions
  1. +1
    -5
      src/main/java/com/inspect/simulator/controller/InfraredController.java
  2. +3
    -1
      src/main/java/com/inspect/simulator/service/HikVisionService.java
  3. +158
    -83
      src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java

+ 1
- 5
src/main/java/com/inspect/simulator/controller/InfraredController.java View File

@ -2,6 +2,7 @@ package com.inspect.simulator.controller;
import com.inspect.simulator.domain.Infrared.Camera; import com.inspect.simulator.domain.Infrared.Camera;
import com.inspect.simulator.domain.Infrared.Coordinate; import com.inspect.simulator.domain.Infrared.Coordinate;
import com.inspect.simulator.domain.Infrared.InfraredInfo;
import com.inspect.simulator.domain.Infrared.NvrInfo; import com.inspect.simulator.domain.Infrared.NvrInfo;
import com.inspect.simulator.service.HikVisionService; import com.inspect.simulator.service.HikVisionService;
import com.inspect.simulator.hikVision.utils.AjaxResult; import com.inspect.simulator.hikVision.utils.AjaxResult;
@ -52,10 +53,5 @@ public class InfraredController {
return hikVisionService.analyzeInfrared(coordinate); return hikVisionService.analyzeInfrared(coordinate);
} }
//调用无人机接口
@PostMapping("/uavInfrared")
public AjaxResult uavInfrared(@RequestParam String apiUrl, @RequestParam String imageUrl, @RequestParam String coordinate) {
return hikVisionService.uavInfrared( apiUrl,imageUrl,coordinate);
}
} }

+ 3
- 1
src/main/java/com/inspect/simulator/service/HikVisionService.java View File

@ -2,6 +2,7 @@ package com.inspect.simulator.service;
import com.inspect.simulator.domain.Infrared.Camera; import com.inspect.simulator.domain.Infrared.Camera;
import com.inspect.simulator.domain.Infrared.Coordinate; import com.inspect.simulator.domain.Infrared.Coordinate;
import com.inspect.simulator.domain.Infrared.InfraredInfo;
import com.inspect.simulator.domain.Infrared.NvrInfo; import com.inspect.simulator.domain.Infrared.NvrInfo;
import com.inspect.simulator.hikVision.utils.AjaxResult; import com.inspect.simulator.hikVision.utils.AjaxResult;
@ -16,5 +17,6 @@ public interface HikVisionService {
//图谱解析 //图谱解析
AjaxResult analyzeInfrared(Coordinate coordinate); AjaxResult analyzeInfrared(Coordinate coordinate);
AjaxResult uavInfrared(String apiUrl, String imageUrl, String coordinate);
//调用华软无人机获取csv温度
public float[][] UploadFtpImage( String url, String type, String image);
} }

+ 158
- 83
src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java View File

@ -4,6 +4,11 @@ package com.inspect.simulator.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.ContentType; import cn.hutool.http.ContentType;
//import com.inspect.simulator.dj.service.DjService; //import com.inspect.simulator.dj.service.DjService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspect.simulator.domain.Infrared.Camera; import com.inspect.simulator.domain.Infrared.Camera;
import com.inspect.simulator.domain.Infrared.Coordinate; import com.inspect.simulator.domain.Infrared.Coordinate;
import com.inspect.simulator.domain.Infrared.InfraredInfo; import com.inspect.simulator.domain.Infrared.InfraredInfo;
@ -16,6 +21,9 @@ import com.inspect.simulator.service.HikVisionService;
import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.IntByReference;
import okhttp3.*;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.aspectj.weaver.ast.Var; import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -34,9 +42,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.*;
import java.util.List; import java.util.List;
/** /**
@ -54,6 +60,12 @@ public class HikVisionServiceImpl implements HikVisionService {
@Value("${file.picPath:test}") @Value("${file.picPath:test}")
private String picPath; private String picPath;
@Value("${file.hrUavUrl:test}")
private String hrUavUrl;
@Value("${file.hrFtpUrl:test}")
private String hrFtpUrl;
// @Override // @Override
// public AjaxResult login(NvrInfo nvrInfo) { // public AjaxResult login(NvrInfo nvrInfo) {
// return login_V40(nvrInfo); // return login_V40(nvrInfo);
@ -260,32 +272,42 @@ public class HikVisionServiceImpl implements HikVisionService {
// } // }
// return AjaxResult.success(infraredInfo); // return AjaxResult.success(infraredInfo);
// } // }
@Override @Override
public AjaxResult analyzeInfrared(Coordinate coordinate) { public AjaxResult analyzeInfrared(Coordinate coordinate) {
InfraredInfo infraredInfo = new InfraredInfo(); InfraredInfo infraredInfo = new InfraredInfo();
try { try {
String imagePath = coordinate.getFilePath(); String imagePath = coordinate.getFilePath();
String imageName = Paths.get(imagePath).getFileName().toString();
String ftpUrlName = "[\"" + hrFtpUrl + imageName + "\"]";
byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath)); byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
if (coordinate.getImgType() == 1) { if (coordinate.getImgType() == 1) {
infraredInfo = readDataHw(imageBytes, coordinate); infraredInfo = readDataHw(imageBytes, coordinate);
} else if (coordinate.getImgType() == 2) { } else if (coordinate.getImgType() == 2) {
String s = ImageOverlaysIvs(coordinate,infraredInfo);
String s = ImageOverlaysIvs(coordinate, infraredInfo);
infraredInfo.setOutPath(s); infraredInfo.setOutPath(s);
} else if (coordinate.getImgType() == 3) { } else if (coordinate.getImgType() == 3) {
// float[][] imageTem = djService.getImageTem(coordinate.getFilePath());
// infraredInfo.setTemperatureMatrix(imageTem);
// String s = ImageOverlaysUav(coordinate, infraredInfo);
// infraredInfo.setOutPath(s);
//sdk版本调用
//float[][] imageTem = djService.getImageTem(coordinate.getFilePath());
//调用华软接口
float[][] imageTem = UploadFtpImage(hrUavUrl, null, ftpUrlName);
if (imageTem != null && imageTem.length > 0 && imageTem[0].length > 0) {
infraredInfo.setTemperatureMatrix(imageTem);
String s = ImageOverlaysUav(coordinate, infraredInfo);
infraredInfo.setOutPath(s);
}else {
return AjaxResult.error("温度解析错误!");
}
} }
return AjaxResult.success(infraredInfo);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return AjaxResult.error(); return AjaxResult.error();
} }
return AjaxResult.success(infraredInfo);
} }
@ -423,7 +445,7 @@ public class HikVisionServiceImpl implements HikVisionService {
InfraredInfo infraredInfo = new InfraredInfo(); InfraredInfo infraredInfo = new InfraredInfo();
// 获取指定坐标的温度 // 获取指定坐标的温度
if (ObjectUtil.isNotEmpty(coordinate.getFirstX())) { if (ObjectUtil.isNotEmpty(coordinate.getFirstX())) {
if (coordinate.getImgType()!=3) {//无人机不需要对比底图
if (coordinate.getImgType() != 3) {//无人机不需要对比底图
//比例缩放像素 获取底图温度值 //比例缩放像素 获取底图温度值
double xMultiple = (coordinate.getImgWidth().doubleValue() / width) * 100 / 100.0; double xMultiple = (coordinate.getImgWidth().doubleValue() / width) * 100 / 100.0;
double yMultiple = (coordinate.getImgHeight().doubleValue() / height) * 100 / 100.0; double yMultiple = (coordinate.getImgHeight().doubleValue() / height) * 100 / 100.0;
@ -450,7 +472,7 @@ public class HikVisionServiceImpl implements HikVisionService {
//存储框选矩阵温度值 //存储框选矩阵温度值
List<Float> values = new ArrayList<>(); List<Float> values = new ArrayList<>();
if (ObjectUtil.isNotEmpty(coordinate.getFirstX()) && ObjectUtil.isNotEmpty(coordinate.getSecondX())) { if (ObjectUtil.isNotEmpty(coordinate.getFirstX()) && ObjectUtil.isNotEmpty(coordinate.getSecondX())) {
if (coordinate.getImgType()!=3) {//无人机不需要对比底图
if (coordinate.getImgType() != 3) {//无人机不需要对比底图
//倍数计算 //倍数计算
double xMultiple = (coordinate.getImgWidth().doubleValue() / width) * 100 / 100.0; double xMultiple = (coordinate.getImgWidth().doubleValue() / width) * 100 / 100.0;
double yMultiple = (coordinate.getImgHeight().doubleValue() / height) * 100 / 100.0; double yMultiple = (coordinate.getImgHeight().doubleValue() / height) * 100 / 100.0;
@ -562,7 +584,7 @@ public class HikVisionServiceImpl implements HikVisionService {
String fileName = file.getName(); String fileName = file.getName();
String pureName = fileName.substring(0, fileName.lastIndexOf('.')); String pureName = fileName.substring(0, fileName.lastIndexOf('.'));
// String imagePath = picPath+"/pic/hw/20250409141218PLAY_CELLPHONE_.jpg"; // String imagePath = picPath+"/pic/hw/20250409141218PLAY_CELLPHONE_.jpg";
String outputPath = picPath + "/pic/hw/mark/" +pureName+"_"+ markPicName + ".jpg";
String outputPath = picPath + "/pic/hw/mark/" + pureName + "_" + markPicName + ".jpg";
try { try {
// 加载原始图片 // 加载原始图片
BufferedImage originalImage = ImageIO.read(new File(imagePath)); BufferedImage originalImage = ImageIO.read(new File(imagePath));
@ -675,7 +697,7 @@ public class HikVisionServiceImpl implements HikVisionService {
String fileName = file.getName(); String fileName = file.getName();
String pureName = fileName.substring(0, fileName.lastIndexOf('.')); String pureName = fileName.substring(0, fileName.lastIndexOf('.'));
// String imagePath = picPath+"/pic/hw/20250409141218PLAY_CELLPHONE_.jpg"; // String imagePath = picPath+"/pic/hw/20250409141218PLAY_CELLPHONE_.jpg";
String outputPath = picPath + "/pic/hw/mark/" +pureName+"_"+ markPicName + ".jpg";
String outputPath = picPath + "/pic/hw/mark/" + pureName + "_" + markPicName + ".jpg";
try { try {
// 加载原始图片 // 加载原始图片
BufferedImage originalImage = ImageIO.read(new File(imagePath)); BufferedImage originalImage = ImageIO.read(new File(imagePath));
@ -703,7 +725,7 @@ public class HikVisionServiceImpl implements HikVisionService {
//矩阵标注 //矩阵标注
if (c.getSecondX() != null && c.getSecondY() != null) { if (c.getSecondX() != null && c.getSecondY() != null) {
// 标注矩形每两个点确定一个矩形 // 标注矩形每两个点确定一个矩形
g2d.setColor(Color.RED);
g2d.setColor(Color.WHITE);
int x1 = c.getFirstX(); int x1 = c.getFirstX();
int y1 = c.getFirstY(); int y1 = c.getFirstY();
int x2 = c.getSecondX(); int x2 = c.getSecondX();
@ -727,12 +749,20 @@ public class HikVisionServiceImpl implements HikVisionService {
coordinate.setSecondY(y2); coordinate.setSecondY(y2);
// 添加矩形标签 // 添加矩形标签
//图片路径取值 //图片路径取值
String[] dividePath = Paths.get(imagePath).getFileName().toString().replace(".jpg", "").split("_");
String[] dividePath = Paths.get(imagePath).getFileName().toString().replaceAll("(?i)\\.jpg$", "").split("_");
String max = dividePath[dividePath.length - 3]; // 最大值 String max = dividePath[dividePath.length - 3]; // 最大值
String min = dividePath[dividePath.length - 2]; // 最小值 String min = dividePath[dividePath.length - 2]; // 最小值
String avg = dividePath[dividePath.length - 1]; // 平均值 String avg = dividePath[dividePath.length - 1]; // 平均值
infraredInfo.setFrameMax(Float.parseFloat(max)); infraredInfo.setFrameMax(Float.parseFloat(max));
g2d.drawString("平均温度:" +avg + "最高温度:" + max + "最低温度:" + min, rectX + 5, rectY + 15);
// g2d.drawString("平均温度:" +avg + "最高温度:" + max + "最低温度:" + min, rectX + 5, rectY + 15);
String line1 = "平均温度:" + avg;
String line2 = "最高温度:" + max;
String line3 = "最低温度:" + min;
g2d.drawString(line1, rectX + 5, rectY + 15);
g2d.drawString(line2, rectX + 5, rectY + 30);
g2d.drawString(line3, rectX + 5, rectY + 45);
} }
} }
} }
@ -764,8 +794,7 @@ public class HikVisionServiceImpl implements HikVisionService {
File file = new File(imagePath); File file = new File(imagePath);
String fileName = file.getName(); String fileName = file.getName();
String pureName = fileName.substring(0, fileName.lastIndexOf('.')); String pureName = fileName.substring(0, fileName.lastIndexOf('.'));
// String imagePath = picPath+"/pic/hw/20250409141218PLAY_CELLPHONE_.jpg";
String outputPath = picPath + "/pic/hw/mark/" +pureName+"_"+markPicName + ".jpg";
String outputPath = picPath + "/pic/hw/mark/" + pureName + "_" + markPicName + ".jpg";
try { try {
// 加载原始图片 // 加载原始图片
BufferedImage originalImage = ImageIO.read(new File(imagePath)); BufferedImage originalImage = ImageIO.read(new File(imagePath));
@ -814,7 +843,7 @@ public class HikVisionServiceImpl implements HikVisionService {
//矩阵标注 //矩阵标注
if (c.getSecondX() != null && c.getSecondY() != null) { if (c.getSecondX() != null && c.getSecondY() != null) {
// 标注矩形每两个点确定一个矩形 // 标注矩形每两个点确定一个矩形
g2d.setColor(Color.GREEN);
g2d.setColor(Color.WHITE);
int x1 = c.getFirstX(); int x1 = c.getFirstX();
int y1 = c.getFirstY(); int y1 = c.getFirstY();
int x2 = c.getSecondX(); int x2 = c.getSecondX();
@ -839,9 +868,13 @@ public class HikVisionServiceImpl implements HikVisionService {
InfraredInfo drawStringMatrix = matrixTemperatureShow(coordinate, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix()); InfraredInfo drawStringMatrix = matrixTemperatureShow(coordinate, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix());
infraredInfo.setFrameMax(Math.round(drawStringMatrix.getFrameMax() * 100) / 100f); infraredInfo.setFrameMax(Math.round(drawStringMatrix.getFrameMax() * 100) / 100f);
// 添加矩形标签 // 添加矩形标签
g2d.drawString("平均温度:" + String.format("%.2f", drawStringMatrix.getFrameAverage()) +
"最高温度:" + String.format("%.2f", drawStringMatrix.getFrameMax()) +
"最低温度:" + String.format("%.2f", drawStringMatrix.getFrameMin()), rectX + 5, rectY + 15);
String line1 = "平均温度:" + String.format("%.2f", drawStringMatrix.getFrameAverage());
String line2 = "最高温度:" + String.format("%.2f", drawStringMatrix.getFrameMax());
String line3 = "最低温度:" + String.format("%.2f", drawStringMatrix.getFrameMin());
g2d.drawString(line1, rectX + 5, rectY + 15);
g2d.drawString(line2, rectX + 5, rectY + 30);
g2d.drawString(line3, rectX + 5, rectY + 45);
} }
} }
} }
@ -862,83 +895,125 @@ public class HikVisionServiceImpl implements HikVisionService {
} }
@Override
public AjaxResult uavInfrared(String apiUrl, String imageUrl, String coordinate) {
apiUrl = "http://192.168.3.81:1000";
imageUrl = "http://192.168.3.81:8080/20230112/t001.jpg";
coordinate = "[[0, 0, 100, 100], [150, 150, 300, 300]]";
public float[][] UploadFtpImage(String url, String type, String image) {
InfraredInfo infraredInfo = new InfraredInfo();
HttpURLConnection connection = null;
type = "ftp";
OkHttpClient client = new OkHttpClient();
float[][] floats = new float[0][];
try { try {
// 1. 创建URL对象
URL url = new URL(apiUrl);
// 构建 multipart 请求体
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("type", type)
.addFormDataPart("image", image)
.build();
// 构建请求
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
.addHeader("Accept", "*/*")
.addHeader("Connection", "keep-alive")
.build();
// 执行请求并处理响应
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("请求失败,HTTP状态码: " + response.code());
}
String responseBody = response.body() != null ? response.body().string() : null;
if (responseBody == null) {
throw new IOException("响应体为空");
}
// 解析 JSON 并提取 image_raw_flow
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonArray = mapper.readTree(responseBody);
if (jsonArray.isEmpty()) {
throw new RuntimeException("JSON数组为空");
}
JsonNode firstItem = jsonArray.get(0);
String imageRawFlow = firstItem.get("image_raw_flow").asText();
floats = parseCsvFromFtp(imageRawFlow);
}
} catch (Exception e) {
System.err.println("请求处理失败: " + e.getMessage());
e.printStackTrace();
}
return floats;
}
// 2. 打开连接
connection = (HttpURLConnection) url.openConnection();
// 3. 设置请求属性
connection.setRequestMethod("POST");
connection.setConnectTimeout(5000); // 5秒连接超时
connection.setReadTimeout(10000); // 10秒读取超时
private float[][] parseCsvFromFtp(String csvUrl) throws IOException {
// 4. 生成boundary分隔符
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
connection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
connection.setDoOutput(true);
FTPClient ftp = new FTPClient();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 5. 构建请求体
try (OutputStream outputStream = connection.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), true)) {
String protocol = hrFtpUrl.substring(0, 6); // "ftp://"
String withoutProtocol = hrFtpUrl.substring(6); // "zthr02:zthr02@123.184.14.138:50021/"
String[] userAndHost = withoutProtocol.split("@");
if (userAndHost.length != 2) {
throw new IllegalArgumentException("URL 格式错误,缺少 @ 分隔符");
}
String[] userPass = userAndHost[0].split(":");
String username = userPass[0];
String password = userPass[1];
String hostPort = userAndHost[1].replace("/", ""); // 移除末尾的 "/"
String[] hostAndPort = hostPort.split(":");
String host = hostAndPort[0];
int port = Integer.parseInt(hostAndPort[1]);
try {
ftp.connect(host, port);
ftp.login(username, password);
ftp.enterLocalPassiveMode();
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 添加image参数
addFormField(writer, boundary, "image", imageUrl);
// 添加type参数(固定值"url")
addFormField(writer, boundary, "type", "url");
String remotePath = csvUrl.replace(protocol + host + ":" + port, "");
// 添加coordinate参数
addFormField(writer, boundary, "coordinate", coordinate);
// 结束标记
writer.append("--").append(boundary).append("--").append("\r\n");
if (!ftp.retrieveFile(remotePath, outputStream)) {
throw new IOException("文件下载失败: " + remotePath);
} }
// 6. 获取响应
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 读取响应内容
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
byte[] csvData = outputStream.toByteArray();
try (InputStream inputStream = new ByteArrayInputStream(csvData);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
List<float[]> rows = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().isEmpty()) {
continue;
}
String[] stringValues = line.split(",");
float[] floatValues = new float[stringValues.length];
for (int i = 0; i < stringValues.length; i++) {
try {
floatValues[i] = Float.parseFloat(stringValues[i].trim());
} catch (NumberFormatException e) {
throw new IOException("Invalid number format in CSV at value: " + stringValues[i], e);
}
} }
String infraredData = response.toString();
rows.add(floatValues);
} }
} else {
return AjaxResult.error("请求失败,HTTP状态码: " + responseCode);
float[][] result = new float[rows.size()][];
for (int i = 0; i < rows.size(); i++) {
result[i] = rows.get(i);
}
return result;
} }
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("请求发生异常: " + e.getMessage());
} finally { } finally {
if (connection != null) {
connection.disconnect();
if (ftp.isConnected()) {
ftp.disconnect();
} }
outputStream.close();
} }
return AjaxResult.success(infraredInfo);
} }
private static void addFormField(PrintWriter writer, String boundary,
String fieldName, String fieldValue) {
writer.append("--").append(boundary).append("\r\n");
writer.append("Content-Disposition: form-data; name=\"")
.append(fieldName).append("\"\r\n\r\n");
writer.append(fieldValue).append("\r\n");
}
} }

Loading…
Cancel
Save