Browse Source

修改图片类型字段值区分;opencv反算获取温度矩阵

master
wangxun 8 months ago
parent
commit
a8e31393ff
6 changed files with 179 additions and 53 deletions
  1. +36
    -3
      pom.xml
  2. +2
    -2
      src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java
  3. +2
    -1
      src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java
  4. +29
    -47
      src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java
  5. +90
    -0
      src/main/java/com/inspect/simulator/tempCount/TempCount.java
  6. +20
    -0
      src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java

+ 36
- 3
pom.xml View File

@ -243,6 +243,42 @@
<artifactId>commons-compress</artifactId>
<version>1.19</version>
</dependency>
<!-- OpenCV -->
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>4.5.5-1</version>
</dependency>
<!-- Apache Commons for file operations -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- For CSV export -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.9.0</version>
</dependency>
<!-- For plotting (similar to matplotlib) -->
<dependency>
<groupId>org.knowm.xchart</groupId>
<artifactId>xchart</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
@ -289,9 +325,6 @@
</plugins>
</build>
</project>

+ 2
- 2
src/main/java/com/inspect/simulator/domain/Infrared/InfraPictureInfo.java View File

@ -29,7 +29,7 @@ public class InfraPictureInfo {
private List<Coordinate> 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;
}

+ 2
- 1
src/main/java/com/inspect/simulator/service/impl/AlgorithmServiceImpl.java View File

@ -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);


+ 29
- 47
src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java View File

@ -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();


+ 90
- 0
src/main/java/com/inspect/simulator/tempCount/TempCount.java View File

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

+ 20
- 0
src/main/java/com/inspect/simulator/tempCount/TemperatureStats.java View File

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

Loading…
Cancel
Save