From a8e31393ff91a5bd107364e3f36cdbfa36f44e88 Mon Sep 17 00:00:00 2001 From: wangxun Date: Thu, 24 Apr 2025 15:14:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=AD=97=E6=AE=B5=E5=80=BC=E5=8C=BA=E5=88=86=EF=BC=9B?= =?UTF-8?q?opencv=E5=8F=8D=E7=AE=97=E8=8E=B7=E5=8F=96=E6=B8=A9=E5=BA=A6?= =?UTF-8?q?=E7=9F=A9=E9=98=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 39 +++++++- .../domain/Infrared/InfraPictureInfo.java | 4 +- .../service/impl/AlgorithmServiceImpl.java | 3 +- .../service/impl/HikVisionServiceImpl.java | 76 ++++++---------- .../simulator/tempCount/TempCount.java | 90 +++++++++++++++++++ .../simulator/tempCount/TemperatureStats.java | 20 +++++ 6 files changed, 179 insertions(+), 53 deletions(-) create mode 100644 src/main/java/com/inspect/simulator/tempCount/TempCount.java create mode 100644 src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java diff --git a/pom.xml b/pom.xml index b16754b..d86f6f4 100644 --- a/pom.xml +++ b/pom.xml @@ -243,6 +243,42 @@ commons-compress 1.19 + + + + + + org.openpnp + opencv + 4.5.5-1 + + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + org.apache.commons + commons-csv + 1.9.0 + + + + + org.knowm.xchart + xchart + 3.8.3 + + + commons-io + commons-io + 2.11.0 + + @@ -289,9 +325,6 @@ - - - diff --git a/src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java b/src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java index f19361b..f39930e 100644 --- a/src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java +++ b/src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java @@ -29,7 +29,7 @@ public class InfraPictureInfo { private List coordinates; - //红外图片类型 1-NVR;2-IVS;3-无人机 - private Integer imgType; + //红外图片类型 INFRA_1800 = "infra_1800"; INFRA_YU3 = "infra_yu3"; INFRA_CAMERA = "infra_camera"; INFRA_CAMERA_REVERSE = "infra_camera_reverse"; + private String imgType; } diff --git a/src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java b/src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java index fbd03b0..c6fa88b 100644 --- a/src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java +++ b/src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java @@ -176,9 +176,10 @@ public class AlgorithmServiceImpl implements AlgorithmService { log.info(Color.MAGENTA + "[INFRARED] irPicAnalyse: channelContent={}" + Color.END, channelContent); String[] imageUrlList = analyseReqItem.getImageUrlList(); + String[] typeListImg = analyseReqItem.getTypeList(); // 调用红外算法 InfraPictureInfo infraPictureInfo = new InfraPictureInfo(); - infraPictureInfo.setImgType(3); + infraPictureInfo.setImgType(typeListImg[0]); infraPictureInfo.setFilePath(imageUrlList[0]); InfraredInfo infraredInfo = hikVisionService.calculatePicture(infraPictureInfo,channelContent); diff --git a/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java b/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java index 27b3f0b..606cf0c 100644 --- a/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java +++ b/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java @@ -24,6 +24,8 @@ import com.inspect.simulator.hikVision.utils.jna.HCNetSDK; import com.inspect.simulator.mapper.BasedataEqpBookChannelMapper; import com.inspect.simulator.service.HikVisionService; import com.inspect.simulator.service.remote.AnalysisRemoteService; +import com.inspect.simulator.tempCount.TempCount; +import com.inspect.simulator.tempCount.TemperatureStats; import com.inspect.simulator.utils.HttpClientUtils; import com.inspect.simulator.utils.sftp.SftpClient; import com.sun.jna.ptr.IntByReference; @@ -67,8 +69,8 @@ public class HikVisionServiceImpl implements HikVisionService { // @Autowired // private HCNetSDK hcNetSDK; - -// @Autowired +// +// @Resource // private DjService djService; @Value("${file.picPath:test}") @@ -95,6 +97,9 @@ public class HikVisionServiceImpl implements HikVisionService { @Resource private SftpClient sftpClient; + @Resource + private TempCount tempCount; + @Resource private BasedataEqpBookChannelMapper basedataEqpBookChannelMapper; @@ -307,11 +312,11 @@ public class HikVisionServiceImpl implements HikVisionService { @Override public AjaxResult capturePicture(InfraPictureInfo infraPictureInfo) { log.info("capturePicture, coordinate:{}", infraPictureInfo); - if (infraPictureInfo.getImgType() == 1) { + if (infraPictureInfo.getImgType().equals("infra_camera_reverse")) { return AjaxResult.success("设置成功"); - } else if (infraPictureInfo.getImgType() == 2) { + } else if (infraPictureInfo.getImgType().equals("infra_1800")) { return AjaxResult.success("设置成功"); - } else if (infraPictureInfo.getImgType() == 3) { + } else if (infraPictureInfo.getImgType().equals("infra_yu3")) { Long channelId = infraPictureInfo.getChannelId(); //channelId = 1299L; BasedataEqpBookChannel basedataEqpBookChannel = basedataEqpBookChannelMapper.selectBasedataEqpBookChannelByChannelId(channelId); @@ -588,35 +593,7 @@ public class HikVisionServiceImpl implements HikVisionService { } } - //NVR返回字符串根据宽高,获取温度矩阵 - private float[][] getMatrix(Integer picWidth, Integer height) { - float[][] tempMatrix = new float[height][picWidth]; - String temperatureStr = "11.00,12.00,12.00,14.00,15.00,22.00,33.00,22.00"; - String[] tempValues = temperatureStr.split(","); - float[] temps = new float[tempValues.length]; - for (int i = 0; i < tempValues.length; i++) { - temps[i] = Float.parseFloat(tempValues[i]); - } - // 初始化矩阵,默认填充0.00 - for (int i = 0; i < height; i++) { - for (int j = 0; j < picWidth; j++) { - tempMatrix[i][j] = 0.00f; - } - } - // 按行优先填充数据 - int index = 0; - for (int i = 0; i < height; i++) { - for (int j = 0; j < picWidth; j++) { - if (index < temps.length) { - tempMatrix[i][j] = temps[index++]; - } else { - break; // 数据用完,剩余保持0.00 - } - } - } - return tempMatrix; - } //图片标注__无人机/ivs1800/nvr public String ImageOverlays(InfraPictureInfo infraPictureInfo, InfraredInfo infraredInfo) { @@ -661,7 +638,7 @@ public class HikVisionServiceImpl implements HikVisionService { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Font font = new Font("微软雅黑", Font.BOLD, 17); - if (infraPictureInfo.getImgType() == 3) { + if (infraPictureInfo.getImgType().equals("infra_yu3")) { for (Coordinate c : coordinates) { //点标注 if (c.getFirstX() != null && c.getFirstY() != null && c.getSecondX() == null && c.getSecondY() == null) { @@ -720,7 +697,7 @@ public class HikVisionServiceImpl implements HikVisionService { } } } - } else if (infraPictureInfo.getImgType() == 2) { + } else if (infraPictureInfo.getImgType().equals("infra_1800")) { for (Coordinate c : coordinates) { g2d.setFont(font); //矩阵标注 @@ -759,12 +736,13 @@ public class HikVisionServiceImpl implements HikVisionService { } } } - } else if (infraPictureInfo.getImgType() == 1) { + } else if (infraPictureInfo.getImgType().equals("infra_camera_reverse")) { for (Coordinate c : coordinates) { + g2d.setFont(font); //矩阵标注 if (c.getSecondX() != null && c.getSecondY() != null) { // 标注矩形(每两个点确定一个矩形) - g2d.setColor(Color.RED); + g2d.setColor(Color.WHITE); int x1 = c.getFirstX(); int y1 = c.getFirstY(); int x2 = c.getSecondX(); @@ -873,6 +851,7 @@ public class HikVisionServiceImpl implements HikVisionService { return null; } return floats; + } //解析获取csv文件温度 @@ -1106,10 +1085,11 @@ public class HikVisionServiceImpl implements HikVisionService { final String feedbackUrl = feedBackHostIp + feedBackPort + "/picAnalyseRetNotify"; log.info("[INFRARED] irPicAnalyse: feedbackUrl={}", feedbackUrl); String[] imageUrlList = analyseReqItem.getImageUrlList(); + String[] typeListImg = analyseReqItem.getTypeList(); InfraPictureInfo infraPictureInfo = new InfraPictureInfo(); // infraPictureInfo.setChannelId(); - infraPictureInfo.setImgType(3); + infraPictureInfo.setImgType(typeListImg[0]); infraPictureInfo.setFilePath(imageUrlList[0]); InfraredInfo infraredInfo = calculatePicture(infraPictureInfo,"1,1,639,511,640,512"); @@ -1181,24 +1161,28 @@ public class HikVisionServiceImpl implements HikVisionService { infraPictureInfo.setImgHeight(imgHeight); infraPictureInfo.setCoordinates(coordinates); - if (infraPictureInfo.getImgType() == 1) { + if (infraPictureInfo.getImgType().equals("infra_camera_reverse")) { //相机红外 // byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath)); // infraredInfo = readDataHw(imageBytes, infraPictureInfo.getCoordinates().get(0)); - float[][] matrix = getMatrix(infraPictureInfo.getImgWidth(), infraPictureInfo.getImgHeight());//图片宽、高 + + InputStream inputStreamPath = downloadFtp(imagePath); + + float[][] matrix = tempCount.countTemp(inputStreamPath,61.20,7.10);//图,最高值,最低值 infraredInfo.setTemperatureMatrix(matrix); //画框标注 String s = ImageOverlays(infraPictureInfo, infraredInfo); infraredInfo.setOutPath(s); - } else if (infraPictureInfo.getImgType() == 2) { + } else if (infraPictureInfo.getImgType().equals("infra_1800")) { //ivs1800红外图 String s = ImageOverlays(infraPictureInfo, infraredInfo); infraredInfo.setOutPath(s); - } else if (infraPictureInfo.getImgType() == 3) { + } else if (infraPictureInfo.getImgType().equals("infra_yu3")) { //无人机红外图 - //sdk版本调用x86_32 - //float[][] imageTem = djService.getImageTem(coordinate.getFilePath()); +// sdk版本调用x64 + +// float[][] imageTem = djService.getImageTem("D:/projects/pic/hw/1.JPG"); //调用华软接口 String protocol = hrFtpUrl.substring(0, 6); // "ftp://" @@ -1227,19 +1211,17 @@ public class HikVisionServiceImpl implements HikVisionService { infraredInfo.setTemperatureMatrix(imageTem); } else { //不能调用华软接口,使用本地csv - System.out.println("温度解析错误,接口无法调用!"); try { imageTem = exceptionHandling(); infraredInfo.setTemperatureMatrix(imageTem); } catch (IOException e) { e.printStackTrace(); - + log.error("温度解析错误,接口无法调用!"); } } String s = ImageOverlays(infraPictureInfo, infraredInfo); infraredInfo.setOutPath(s); } else { - System.out.println("温度解析错误,ftp无法登陆!"); //华软ftp不能登录,使用本地csv try { imageTem = exceptionHandling(); diff --git a/src/main/java/com/inspect/simulator/tempCount/TempCount.java b/src/main/java/com/inspect/simulator/tempCount/TempCount.java new file mode 100644 index 0000000..c710e7a --- /dev/null +++ b/src/main/java/com/inspect/simulator/tempCount/TempCount.java @@ -0,0 +1,90 @@ +package com.inspect.simulator.tempCount; + +import org.opencv.core.Mat; +import org.opencv.core.MatOfByte; +import org.opencv.imgcodecs.Imgcodecs; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; +import java.io.*; + + +@Configuration +public class TempCount { + + @PostConstruct + public void init() { + nu.pattern.OpenCV.loadLocally(); + } + + //通过最大最小温度值反算温度矩阵 + public float[][] countTemp(InputStream imageStream , Double maxTemp,Double minTemp) { + + float[][] temperatureMatrix=new float[0][]; + try { + temperatureMatrix = processInfraredImage(imageStream,maxTemp,minTemp); + // 计算统计值 + TemperatureStats stats = calculateStats(temperatureMatrix); + // 打印统计结果 + System.out.printf("温度统计:\n 最低: %.2f°C\n 最高: %.2f°C\n", stats.minTemp, stats.maxTemp); + + } catch (Exception e) { + System.err.println("处理失败: " + e.getMessage()); + e.printStackTrace(); + } + return temperatureMatrix; + } + + public float[][] processInfraredImage(InputStream imageStream,Double maxTemp,Double minTemp) throws IOException { + //校准参数(max的差值min)/255 + if (maxTemp == null || minTemp == null) { + throw new IllegalArgumentException("温度值不能为null"); + } + if (imageStream == null) { + throw new IllegalArgumentException("输入流不能为null"); + } + + // 将InputStream转换为字节数组 + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + byte[] data = new byte[1024]; + int nRead; + while ((nRead = imageStream.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + buffer.flush(); + byte[] imageBytes = buffer.toByteArray(); + + // 2. 解码图像 + Mat img = Imgcodecs.imdecode(new MatOfByte(imageBytes), Imgcodecs.IMREAD_GRAYSCALE); + if (img.empty()) { + throw new IOException("无法解码图像流"); + } + + // 2. 创建温度矩阵 + // 计算绝对差值,并保留2位小数 + double deviation = Math.abs(maxTemp - minTemp)/ 255; + float[][] temperatureMatrix = new float[img.rows()][img.cols()]; + + // 3. 转换为温度数据 + for (int i = 0; i < img.rows(); i++) { + for (int j = 0; j < img.cols(); j++) { + // 计算温度: T = a * pixel + b + double temp = (deviation * img.get(i, j)[0]) + minTemp; + // 限制在最低温--最高温范围 + temp = Math.max(minTemp, Math.min(maxTemp, temp)); + temperatureMatrix[i][j] = (float) temp; + } + } + + return temperatureMatrix; + } + public TemperatureStats calculateStats(float[][] matrix) { + TemperatureStats stats = new TemperatureStats(); + for (float[] row : matrix) { + for (float temp : row) { + stats.update(temp); + } + } + return stats; + } +} diff --git a/src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java b/src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java new file mode 100644 index 0000000..5574a3a --- /dev/null +++ b/src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java @@ -0,0 +1,20 @@ +package com.inspect.simulator.tempCount; + +public class TemperatureStats { + + double minTemp = Double.MAX_VALUE; + double maxTemp = Double.MIN_VALUE; + double sumTemp = 0; + int count = 0; + + void update(double temp) { + minTemp = Math.min(minTemp, temp); + maxTemp = Math.max(maxTemp, temp); + sumTemp += temp; + count++; + } + + double getAvgTemp() { + return sumTemp / count; + } +}