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