diff --git a/src/main/java/com/example/lxcameraapi/controller/HikController.java b/src/main/java/com/example/lxcameraapi/controller/HikController.java index 3c67448..026116a 100644 --- a/src/main/java/com/example/lxcameraapi/controller/HikController.java +++ b/src/main/java/com/example/lxcameraapi/controller/HikController.java @@ -8,6 +8,7 @@ import com.example.lxcameraapi.service.IndustrialCamera.distinguish.Calibration; import com.example.lxcameraapi.service.IndustrialCamera.distinguish.FeatureMatchingExample; import com.example.lxcameraapi.service.IndustrialCamera.pojo.Pojo; import com.example.lxcameraapi.yolo.ClassifyEntity; +import lombok.extern.slf4j.Slf4j; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.springframework.web.bind.annotation.GetMapping; @@ -28,6 +29,7 @@ import java.util.UUID; @RestController @RequestMapping("/hik") +@Slf4j public class HikController { @Resource AppConfig appConfig; @@ -65,7 +67,7 @@ public class HikController { if (camera == null){ return "未找到相机"; } - System.out.println(path); + log.info("标定图片路径: {}", path); Mat img2 = Imgcodecs.imread(path);; // 保存图片 @@ -114,9 +116,9 @@ public class HikController { } } } else { - System.out.println("The folder is empty.");} + log.warn("模板文件夹为空: {}", folderPath);} } else { - System.out.println("The specified path is not a valid directory or does not exist."); + log.warn("模板文件夹不存在: {}", folderPath); } @@ -194,7 +196,7 @@ public class HikController { public Pojo distinguishOnnxTest(String streetNumber,int direction, String category) throws IOException { String picPath = "D:\\PycharmProjects\\yolo\\puer\\train\\0286\\1_1fc8f82d-0836-4c82-a683-d5d37d953492.jpg.jpg"; Mat img2 = Imgcodecs.imread(picPath);; - img2 = Calibration.performCalibrationToSquare(img2, 1, appConfig.getActualRectangularRatio(),1024); + img2 = Calibration.performCalibrationToSquare(img2, 1,1024); // 进行标定,保存图片 @@ -234,7 +236,7 @@ public class HikController { boolean i = hikSaveImage.saveImage(camera.getIp(),picPath+ path, "ip"); img2 = Imgcodecs.imread(picPath+path);; - img2 = Calibration.performCalibrationToSquare(img2, camera.getId(), appConfig.getActualRectangularRatio(),1024); + img2 = Calibration.performCalibrationToSquare(img2, camera.getId(), 1024); } } @@ -244,11 +246,11 @@ public class HikController { boolean flag = false; try { ClassifyEntity classifyEntity = onnxServiceNew.classifyOne(picPath+path+".jpg", null); - if (classifyEntity.getName().equals(category)){ + if (classifyEntity !=null && classifyEntity.getName() !=null && classifyEntity.getName().equals(category)){ flag = true; }else { for (List similar:appConfig.getSimilar()){ - if (similar.contains(classifyEntity.getName())){ + if (classifyEntity !=null && classifyEntity.getName() !=null && similar.contains(classifyEntity.getName())){ flag = true; } } diff --git a/src/main/java/com/example/lxcameraapi/service/IndustrialCamera/distinguish/Calibration.java b/src/main/java/com/example/lxcameraapi/service/IndustrialCamera/distinguish/Calibration.java index 6f1929d..962ca07 100644 --- a/src/main/java/com/example/lxcameraapi/service/IndustrialCamera/distinguish/Calibration.java +++ b/src/main/java/com/example/lxcameraapi/service/IndustrialCamera/distinguish/Calibration.java @@ -1,6 +1,7 @@ package com.example.lxcameraapi.service.IndustrialCamera.distinguish; import com.example.lxcameraapi.conf.AppConfig; +import lombok.extern.slf4j.Slf4j; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.core.Size; @@ -13,22 +14,23 @@ import javax.annotation.Resource; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +@Slf4j public class Calibration { static Map boxPositionConf = new ConcurrentHashMap<>(); public static Mat performCalibration(Mat img,Integer cameraId,Double widthRatio){ - // 读取图像 - if (img.empty()) { - System.out.println("Could not open or find the image"); + log.error("图像为空"); return null; } - Point[] worldPoints= adjustPoints( widthRatio); + Point[] worldPoints = adjustPoints(widthRatio); + log.info("开始标定校准, cameraId={}", cameraId); // 创建 Mat 对象来存储四个点 Mat srcPoints = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(boxPositionConf.get(cameraId))); @@ -46,92 +48,118 @@ public class Calibration { return warpedImage; } - public static Mat performCalibrationToSquare(Mat img, Integer cameraId, Double widthRatio, int squareSize) { + /** + * 将图像中指定四边形区域转换为正方形 + * @param img 源图像 + * @param cameraId 相机ID(用于获取配置的四边形角点) + * @param squareSize 正方形尺寸 + * @return 转换后的正方形图像 + */ + public static Mat performCalibrationToSquare(Mat img, Integer cameraId, int squareSize) { if (img.empty()) { - System.out.println("Could not open or find the image"); + log.error("图像为空"); return null; } - Point[] worldPoints = adjustPoints(widthRatio); + Point[] srcPoints = boxPositionConf.get(cameraId); + if (srcPoints == null) { + log.error("未找到相机 {} 的配置", cameraId); + return null; + } - // 创建 Mat 对象来存储四个点 - Mat srcPoints = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(boxPositionConf.get(cameraId))); - Mat dstPoints = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(worldPoints)); + // 目标正方形的四个角点 + Point[] dstPoints = new Point[] { + new Point(0, 0), // 左上 + new Point(squareSize, 0), // 右上 + new Point(0, squareSize), // 左下 + new Point(squareSize, squareSize) // 右下 + }; + + Mat srcMat = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(srcPoints)); + Mat dstMat = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(dstPoints)); // 计算透视变换矩阵 - Mat perspectiveMatrix = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); + Mat perspectiveMatrix = Imgproc.getPerspectiveTransform(srcMat, dstMat); // 应用透视变换,输出为指定大小的正方形 Mat warpedImage = new Mat(); Size outputSize = new Size(squareSize, squareSize); Imgproc.warpPerspective(img, warpedImage, perspectiveMatrix, outputSize); + log.info("标定校准完成, cameraId={}, 输出尺寸={}", cameraId, squareSize); return warpedImage; } public static Mat performCalibration(Mat img,Double widthRatio){ - // 读取图像 - if (img.empty()) { - System.out.println("Could not open or find the image"); + log.error("图像为空"); return null; } - Point[] worldPoints= adjustPoints(0.6 ); + Point[] worldPoints = adjustPoints(0.6); Point[] points = new Point[] { - new Point(1277, 86), // 世界坐标系中的第一个点 - new Point(3004, 341), // 世界坐标系中的第二个点 - new Point(1286, 1478), // 世界坐标系中的第三个点 - new Point(2968, 1325) // 世界坐标系中的第四个点 + new Point(1277, 86), + new Point(3004, 341), + new Point(1286, 1478), + new Point(2968, 1325) }; - // 创建 Mat 对象来存储四个点 + Mat srcPoints = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(points)); Mat dstPoints = Converters.vector_Point2f_to_Mat(java.util.Arrays.asList(worldPoints)); - // 计算透视变换矩阵 Mat perspectiveMatrix = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); - - // 获取输出图像的大小 Size size = img.size(); - // 应用透视变换 Mat warpedImage = new Mat(); Imgproc.warpPerspective(img, warpedImage, perspectiveMatrix, size); + log.info("标定校准完成"); return warpedImage; } + public static void init(List cameras){ - for (AppConfig.Camera camera :cameras) { - String filePath = camera.getCalibratePath(); - Point[] worldPoints = new Point[4]; - try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { - String line; - String[] numbers = new String[0]; - int i = 0; - while ((line = br.readLine()) != null) { - - // 删除 = 及其之前的部分 - String result = line.substring(line.indexOf('=') + 1); - - // 去掉方括号 - result = result.replace("[", "").replace("]", ""); - - // 使用 split 方法分割数字 - numbers = result.split(",\\s*"); - - Point point = new Point(Double.parseDouble(numbers[0]),Double.parseDouble(numbers[1].trim())); - worldPoints[i] = point; - i++; - } - boxPositionConf.put(camera.getId(),worldPoints); - } catch (IOException e) { - e.printStackTrace(); - } - - } + for (AppConfig.Camera camera : cameras) { + String filePath = camera.getCalibratePath(); + Point[] points = parseConfigFile(filePath); + if (points != null) { + boxPositionConf.put(camera.getId(), points); + log.info("相机 {} 标定配置加载成功: {}", camera.getId(), Arrays.toString(points)); + } else { + log.error("相机 {} 标定配置加载失败: {}", camera.getId(), filePath); + } + } } - public static Point[] adjustPoints( double widthRatio) { + /** + * 解析配置文件,返回 Point[] 数组 + * 文件格式: + * topLeft=[321, 761] + * topRight=[1862, 575] + * bottomLeft=[277, 1698] + * bottomRight=[1878, 1906] + */ + public static Point[] parseConfigFile(String filePath) { + Point[] points = new Point[4]; + try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { + String line; + int index = 0; + while ((line = br.readLine()) != null && index < 4) { + String result = line.substring(line.indexOf('=') + 1); + result = result.replace("[", "").replace("]", ""); + String[] numbers = result.split(",\\s*"); + if (numbers.length >= 2) { + points[index] = new Point(Double.parseDouble(numbers[0]), Double.parseDouble(numbers[1].trim())); + index++; + } + } + return points; + } catch (IOException e) { + log.error("读取标定配置文件失败: {}", filePath, e); + return null; + } + } + public static Point[] adjustPoints( double widthRatio) { +// // 世界坐标系中的四个点(你需要根据实际情况替换) Point[] points = new Point[] { new Point(0, 0), // 世界坐标系中的第一个点 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0a3aa5a..8af8f92 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,6 +2,12 @@ spring: application: name: LxCameraApi +# 日志配置 +logging: + level: + root: INFO + com.example.lxcameraapi: DEBUG + server: port: 8097 #两台相机 diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..e79d20b --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,79 @@ + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + UTF-8 + + + + + + ${LOG_PATH}/app.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + UTF-8 + + + INFO + ACCEPT + DENY + + + ${LOG_PATH}/app.%d{yyyy-MM-dd}.log + 30 + 1GB + + + + + + ${LOG_PATH}/error.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + UTF-8 + + + ERROR + + + ${LOG_PATH}/error.%d{yyyy-MM-dd}.log + 30 + 500MB + + + + + + ${LOG_PATH}/debug.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + UTF-8 + + + DEBUG + ACCEPT + DENY + + + ${LOG_PATH}/debug.%d{yyyy-MM-dd}.log + 30 + 500MB + + + + + + + + + + + + + +