You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lxCameraApi/src/main/java/com/example/lxcameraapi/service/AsyncProcessingService.java

207 lines
8.3 KiB
Java

package com.example.lxcameraapi.service;
import ai.onnxruntime.OrtException;
import com.example.lxcameraapi.conf.AppConfig;
import com.example.lxcameraapi.service.IndustrialCamera.algorithm.ONNXServiceNew;
import com.example.lxcameraapi.service.IndustrialCamera.camera.lx.LxCameraService;
import com.example.lxcameraapi.service.IndustrialCamera.camera.lx.config.BoxCountRequest;
import com.example.lxcameraapi.service.IndustrialCamera.camera.lx.config.BoxCountResult;
import com.example.lxcameraapi.service.IndustrialCamera.camera.lx.config.CaptureResult;
import com.example.lxcameraapi.service.IndustrialCamera.opencv.OpencvService;
import com.example.lxcameraapi.service.IndustrialCamera.yolo.BoundingBox;
import com.example.lxcameraapi.service.IndustrialCamera.QrCode.WeChatDeCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.imageio.ImageIO;
@Slf4j
@Service
public class AsyncProcessingService {
@Resource
private ONNXServiceNew onnxServiceNew;
@Resource
private OpencvService opencvService;
@Resource
private LxCameraService lxCameraService;
@Resource
private HttpNotifyService httpNotifyService;
@Resource
private AppConfig appConfig;
/**
*
*/
@Async
public void processCategoryAsync(BoxCountRequest request, String path, String url,
String targetIp, Integer targetPort, String targetPath) {
try {
log.info("异步品规识别任务开始");
List<BoundingBox> detectResults = onnxServiceNew.detect26(path, null);
opencvService.drawBoundingBoxesOnImage(detectResults, path, path + "detect.jpg");
log.info("检测结果: {}", detectResults);
String result = "Unknown";
if (!detectResults.isEmpty()) {
// 统计每个 index 出现的次数
Map<Integer, Long> indexCountMap = detectResults.stream()
.collect(Collectors.groupingBy(
BoundingBox::getIndex,
Collectors.counting()
));
// 找到出现次数最多的 index
Map.Entry<Integer, Long> maxIndexEntry = indexCountMap.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElse(null);
if (maxIndexEntry != null) {
// 根据最多的 index 找到对应的 name
result = detectResults.stream()
.filter(box -> box.getIndex().equals(maxIndexEntry.getKey()))
.findFirst()
.map(BoundingBox::getName)
.orElse("Unknown");
log.info("检测结果统计 - 最常见的类别: {}, 出现次数: {}", result, maxIndexEntry.getValue());
}
}
// 发送HTTP通知到 singleInventoryReturn
if (targetIp != null && targetPort != null && targetPath != null) {
httpNotifyService.sendBoxCountResult(targetIp, targetPort, targetPath,
request.getTaskId(), request.getScanType(), result, url, 0);
} else {
log.warn("异步任务完成,但未配置目标服务器信息");
}
} catch (OrtException e) {
log.error("异步品规识别异常", e);
} catch (Exception e) {
log.error("异步品规识别异常", e);
}
}
/**
*
*/
@Async
public void processBoxCountAsync(BoxCountRequest request, CaptureResult captureResult,
String targetIp, Integer targetPort, String targetPath) {
try {
log.info("异步箱子计数任务开始");
request.setPcdFilePath(captureResult.getFilePath("pointCloud"));
BoxCountResult result = lxCameraService.countBoxes(request);
log.info("箱子数量计算结果: {}", result.getSummary());
String imagePath = captureResult.getFilePath("rgb").replace(appConfig.getPicPath(), appConfig.getPicUrl());
String resultStr = String.valueOf(result.getTotalBoxCount());
// 发送HTTP通知到 singleInventoryReturn
if (targetIp != null && targetPort != null && targetPath != null) {
httpNotifyService.sendBoxCountResult(targetIp, targetPort, targetPath,
request.getTaskId(), request.getScanType(), resultStr, imagePath, result.getTotalBoxCount());
} else {
log.warn("异步任务完成,但未配置目标服务器信息");
}
} catch (Exception e) {
log.error("异步箱子计数异常", e);
}
}
/**
*
*/
@Async
public void processQrCodeAsync(Integer cameraId, String taskId, String path, String url,
String targetIp, Integer targetPort, String targetPath, String scanType) {
try {
log.info("异步识别任务开始,路径: {}", path);
List<BoundingBox> detectResults = onnxServiceNew.detect26(path, "qrCode");
opencvService.drawBoundingBoxesOnImage(detectResults, path, path + ".jpg");
log.info("异步检测结果: {}", detectResults);
// 读取原始图片
BufferedImage originalImage = ImageIO.read(new File(path));
if (originalImage == null) {
log.error("异步任务:无法读取图片: {}", path);
return;
}
// 存储解码结果
List<String> qrCodeResults = new ArrayList<>();
for (BoundingBox box : detectResults) {
try {
BufferedImage croppedImage = cropBoundingBox(originalImage, box, 30);
ImageIO.write(croppedImage, "jpg", new File(path + "_" + box.getIndex() + ".jpg"));
String qrCodeContent = WeChatDeCode.deCode(croppedImage);
qrCodeResults.add(qrCodeContent);
if (qrCodeContent != null) {
log.info("异步解码成功: {}, 置信度: {}", qrCodeContent, box.getConfidence());
} else {
log.warn("异步解码失败box: {}", box);
}
} catch (Exception e) {
log.error("异步解码二维码异常box: {}", box, e);
}
}
// 构建结果
String result = qrCodeResults.size() > 0 ? qrCodeResults.get(0).substring(0, 8) : "Unknown";
String imagePath = url + ".jpg";
// 发送HTTP通知到 singleInventoryQrCodeReturn
if (targetIp != null && targetPort != null && targetPath != null) {
httpNotifyService.sendQrCodeResult(targetIp, targetPort, targetPath, taskId, result, imagePath, qrCodeResults, scanType);
} else {
log.warn("异步任务完成,但未配置目标服务器信息");
}
} catch (Exception e) {
log.error("异步任务执行异常", e);
}
}
private BufferedImage cropBoundingBox(BufferedImage originalImage, BoundingBox box, int expandPixels) {
int imageWidth = originalImage.getWidth();
int imageHeight = originalImage.getHeight();
int x = (int) box.getX();
int y = (int) box.getY();
int width = (int) box.getW();
int height = (int) box.getH();
x = x - expandPixels;
y = y - expandPixels;
width = width + (expandPixels * 2);
height = height + (expandPixels * 2);
x = Math.max(0, Math.min(x, imageWidth - 1));
y = Math.max(0, Math.min(y, imageHeight - 1));
width = Math.min(width, imageWidth - x);
height = Math.min(height, imageHeight - y);
width = Math.max(1, width);
height = Math.max(1, height);
return originalImage.getSubimage(x, y, width, height);
}
}