修改旧有bug

普洱算法
LAPTOP-S9HJSOEB\昊天 2 months ago
parent 788c8bc42b
commit 8530a86cfd

@ -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<String> similar:appConfig.getSimilar()){
if (similar.contains(classifyEntity.getName())){
if (classifyEntity !=null && classifyEntity.getName() !=null && similar.contains(classifyEntity.getName())){
flag = true;
}
}

@ -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<Integer,Point[]> 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<AppConfig.Camera> 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), // 世界坐标系中的第一个点

@ -2,6 +2,12 @@ spring:
application:
name: LxCameraApi
# 日志配置
logging:
level:
root: INFO
com.example.lxcameraapi: DEBUG
server:
port: 8097
#两台相机

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定义日志目录 -->
<property name="LOG_PATH" value="logs"/>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Info 日志文件,按天分离 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/app.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- Error 日志文件,按天分离 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/error.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>500MB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- Debug 日志文件 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/debug.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/debug.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>500MB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 根日志配置 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!-- 指定包的日志级别 -->
<logger name="com.example.lxcameraapi" level="DEBUG"/>
<logger name="com.example.lxcameraapi.controller" level="DEBUG"/>
</configuration>
Loading…
Cancel
Save