1
This commit is contained in:
@@ -201,16 +201,15 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
if (!enableDetection) return;
|
||||
|
||||
modelManager = new ModelManager();
|
||||
URL json = getClass().getResource("/models/models.json");
|
||||
URL json = getClass().getResource("/libs/models/models.json");
|
||||
modelManager.load(json);
|
||||
|
||||
// 你可按需切换单模型或多模型并行
|
||||
// detector = modelManager.get("person-helmet");
|
||||
detector = new CompositeDetector(
|
||||
"all-models",
|
||||
java.util.List.of(
|
||||
modelManager.get("person-helmet"),
|
||||
modelManager.get("vehicle-plate")
|
||||
modelManager.get("garbage"),
|
||||
modelManager.get("smoke")
|
||||
),
|
||||
2 // 并行度
|
||||
);
|
||||
@@ -345,6 +344,7 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
if (enableDetection) initDetectors();
|
||||
} catch (Exception e) {
|
||||
log.error("初始化检测模型失败:{}", e.getMessage(), e);
|
||||
// 模型失败不影响推流,但不禁用检测
|
||||
}
|
||||
|
||||
if (!createGrabber()) return;
|
||||
@@ -367,7 +367,7 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
final long DETECTION_INTERVAL_MS = 3000; // 每3秒检测一次
|
||||
long lastDetectionTime = 0;
|
||||
List<Detection> currentDetections = Collections.emptyList(); // 当前显示的检测结果
|
||||
|
||||
|
||||
for (; running && grabberStatus && recorderStatus; ) {
|
||||
try {
|
||||
if (transferFlag) {
|
||||
@@ -395,48 +395,48 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
closeMedia();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (frame != null && enableDetection) {
|
||||
// 将Frame转换为Mat以进行处理
|
||||
Mat mat = toMat.convert(frame);
|
||||
|
||||
|
||||
if (mat != null && !mat.empty()) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
// 每隔DETECTION_INTERVAL_MS执行一次检测
|
||||
if (currentTime - lastDetectionTime >= DETECTION_INTERVAL_MS) {
|
||||
try {
|
||||
log.debug("执行新一轮检测,上次检测时间: {}ms前",
|
||||
log.debug("执行新一轮检测,上次检测时间: {}ms前",
|
||||
currentTime - lastDetectionTime);
|
||||
|
||||
|
||||
// 创建副本进行检测
|
||||
Mat detectionMat = new Mat();
|
||||
mat.copyTo(detectionMat);
|
||||
|
||||
|
||||
// 执行检测
|
||||
currentDetections = detector.detect(detectionMat);
|
||||
lastDetectionTime = currentTime;
|
||||
latestDetections.set(currentDetections);
|
||||
|
||||
|
||||
// 释放检测Mat
|
||||
detectionMat.release();
|
||||
|
||||
|
||||
// 窗口巡检回调
|
||||
if (windowMode && detectionListener != null &&
|
||||
if (windowMode && detectionListener != null &&
|
||||
currentJobId != null && currentDeviceId != null) {
|
||||
detectionListener.onDetections(currentJobId,
|
||||
currentDeviceId,
|
||||
currentDetections,
|
||||
detectionListener.onDetections(currentJobId,
|
||||
currentDeviceId,
|
||||
currentDetections,
|
||||
currentTime);
|
||||
}
|
||||
|
||||
log.debug("检测完成,发现 {} 个目标,框将保持3秒",
|
||||
|
||||
log.debug("检测完成,发现 {} 个目标,框将保持3秒",
|
||||
currentDetections == null ? 0 : currentDetections.size());
|
||||
} catch (Exception e) {
|
||||
log.debug("检测异常: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 每一帧都使用最新的检测结果绘制框
|
||||
// 这样框会保持在原位置,直到下一次检测更新
|
||||
if (currentDetections != null && !currentDetections.isEmpty()) {
|
||||
@@ -447,24 +447,24 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
log.debug("绘制检测框异常: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新"最近叠好框的帧"用于存证
|
||||
updateLatestAnnotated(mat);
|
||||
|
||||
|
||||
// 统计(仅窗口巡检时)
|
||||
if (windowMode) updateStats(currentDetections);
|
||||
|
||||
|
||||
// 窗口结束判定
|
||||
if (windowMode && System.currentTimeMillis() >= windowEndMs) {
|
||||
finishWindow();
|
||||
}
|
||||
|
||||
|
||||
// 将处理后的Mat转换回Frame
|
||||
try {
|
||||
// 创建新的转换器
|
||||
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
|
||||
Frame processedFrame = converter.convert(mat);
|
||||
|
||||
|
||||
if (processedFrame != null) {
|
||||
// 使用处理后的帧替换原始帧
|
||||
frame = processedFrame;
|
||||
@@ -473,7 +473,7 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
|
||||
log.debug("Mat转Frame异常: {}", e.getMessage());
|
||||
// 如果转换失败,继续使用原始帧
|
||||
}
|
||||
|
||||
|
||||
// 释放Mat
|
||||
mat.release();
|
||||
}
|
||||
|
||||
@@ -25,15 +25,9 @@ public final class OpenVinoYoloDetector implements YoloDetector {
|
||||
this.input = new Size(inW, inH);
|
||||
this.colorBGR = colorBGR;
|
||||
|
||||
// 自动查找模型文件
|
||||
String xml = findModelFile(dir, ".xml");
|
||||
String bin = findModelFile(dir, ".bin");
|
||||
String xml = dir.resolve("model.xml").toString();
|
||||
String bin = dir.resolve("model.bin").toString();
|
||||
|
||||
if (xml == null || bin == null) {
|
||||
throw new Exception("找不到模型文件,请确保目录中存在 .xml 和 .bin 文件: " + dir);
|
||||
}
|
||||
|
||||
// 读取类别文件
|
||||
Path clsPath = dir.resolve("classes.txt");
|
||||
if (Files.exists(clsPath)) {
|
||||
this.classes = Files.readAllLines(clsPath).stream().map(String::trim)
|
||||
@@ -42,34 +36,19 @@ public final class OpenVinoYoloDetector implements YoloDetector {
|
||||
this.classes = new String[0];
|
||||
}
|
||||
|
||||
try {
|
||||
// 加载模型,但强制使用OpenCV后端
|
||||
this.net = readNetFromModelOptimizer(xml, bin);
|
||||
|
||||
// 强制使用OpenCV后端,避免OpenVINO依赖
|
||||
this.net = readNetFromModelOptimizer(xml, bin);
|
||||
|
||||
boolean set = false;
|
||||
if ("openvino".equalsIgnoreCase(backend)) {
|
||||
try {
|
||||
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
net.setPreferableTarget(DNN_TARGET_CPU);
|
||||
set = true;
|
||||
} catch (Throwable ignore) { /* 回退 */ }
|
||||
}
|
||||
if (!set) {
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(DNN_TARGET_CPU);
|
||||
|
||||
System.out.println("模型加载成功: " + name + " (使用OpenCV后端)");
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new Exception("模型加载失败: " + e.getMessage() +
|
||||
"\n请确保模型文件完整且格式正确", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在目录中查找指定扩展名的模型文件
|
||||
*/
|
||||
private String findModelFile(Path dir, String extension) {
|
||||
try {
|
||||
return Files.list(dir)
|
||||
.filter(path -> path.toString().toLowerCase().endsWith(extension.toLowerCase()))
|
||||
.map(Path::toString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,4 +227,4 @@ public final class OpenVinoYoloDetector implements YoloDetector {
|
||||
}
|
||||
|
||||
@Override public void close(){ net.close(); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user