mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-13 21:28:52 +00:00
优化视频目标检测
This commit is contained in:
@@ -49,7 +49,6 @@ public class StreamDetector implements AutoCloseable{
|
||||
//回调线程池
|
||||
ExecutorService callbackExecutor;
|
||||
private int frameDetectionInterval = 1;
|
||||
private long repeatGap = 5; // 秒
|
||||
private volatile boolean isRunning;
|
||||
private FrameGrabber grabber;
|
||||
private StreamDetectionListener listener;
|
||||
@@ -57,6 +56,8 @@ public class StreamDetector implements AutoCloseable{
|
||||
private VideoSourceType sourceType = VideoSourceType.STREAM; // 默认流
|
||||
private int cameraIndex = 0; // 默认第一个摄像头
|
||||
|
||||
private boolean enableDebugLog; //是否开启debug log
|
||||
|
||||
private Map<String, Long> lastDetectTime = new ConcurrentHashMap<>();
|
||||
private BlockingQueue<Frame> frameQueue = new LinkedBlockingQueue<>(100);
|
||||
|
||||
@@ -84,7 +85,8 @@ public class StreamDetector implements AutoCloseable{
|
||||
this.listener = builder.listener;
|
||||
this.sourceType = builder.sourceType;
|
||||
this.cameraIndex = builder.cameraIndex;
|
||||
this.repeatGap = builder.repeatGap;
|
||||
// this.repeatGap = builder.repeatGap;
|
||||
this.enableDebugLog = builder.enableDebugLog;
|
||||
this.converterToMat = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
|
||||
}
|
||||
|
||||
@@ -160,7 +162,7 @@ public class StreamDetector implements AutoCloseable{
|
||||
* 负责抓取视频帧到队列
|
||||
*/
|
||||
private void processFrames() {
|
||||
long frameCount = 0;
|
||||
long detectCounter = 0;
|
||||
while (!grabberFinished && isRunning) {
|
||||
try {
|
||||
Frame frame = grabber.grabFrame();
|
||||
@@ -192,11 +194,16 @@ public class StreamDetector implements AutoCloseable{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
frameCount++;
|
||||
if (frameCount % frameDetectionInterval != 0) continue;
|
||||
detectCounter++;
|
||||
if (detectCounter < frameDetectionInterval) {
|
||||
continue;
|
||||
}
|
||||
detectCounter = 0;
|
||||
Frame currentFrame = frame.clone();
|
||||
frameQueue.offer(currentFrame);
|
||||
// log.debug("正在抓取第{}帧,当前帧数:{}", frameCount, frameQueue.size());
|
||||
if (enableDebugLog){
|
||||
log.debug("当前未处理帧数:{}", frameQueue.size());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("抓取视频帧异常", e);
|
||||
}
|
||||
@@ -242,16 +249,15 @@ public class StreamDetector implements AutoCloseable{
|
||||
|
||||
Image image = SmartImageFactory.getInstance().fromMat(mat);
|
||||
DetectedObjects detectedObjects = predictor.predict(image);
|
||||
// log.info("内部检测结果:{}", detectedObjects.toString());
|
||||
if (enableDebugLog){
|
||||
log.debug("帧检测结果:{}", detectedObjects.toString());
|
||||
}
|
||||
DetectionResponse detectionResponse = DetectorUtils.convertToDetectionResponse(detectedObjects, image);
|
||||
if(Objects.isNull(detectionResponse)){
|
||||
return;
|
||||
}
|
||||
List<DetectionInfo> filtered = filterRepeatedObjects(detectionResponse);
|
||||
if (!filtered.isEmpty() && listener != null) {
|
||||
Image copyImage = image.duplicate();
|
||||
callbackExecutor.submit(() -> listener.onObjectDetected(filtered, copyImage));
|
||||
}
|
||||
Image copyImage = image.duplicate();
|
||||
callbackExecutor.submit(() -> listener.onObjectDetected(detectionResponse.getDetectionInfoList(), copyImage));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
log.error("单帧处理异常", e);
|
||||
@@ -260,21 +266,6 @@ public class StreamDetector implements AutoCloseable{
|
||||
}
|
||||
}
|
||||
|
||||
private List<DetectionInfo> filterRepeatedObjects(DetectionResponse response) {
|
||||
List<DetectionInfo> result = new ArrayList<>();
|
||||
long now = System.currentTimeMillis();
|
||||
for (DetectionInfo info : response.getDetectionInfoList()) {
|
||||
String name = info.getObjectDetInfo().getClassName();
|
||||
Long last = lastDetectTime.get(name);
|
||||
if (last == null || (now - last) > repeatGap * 1000) {
|
||||
lastDetectTime.put(name, now);
|
||||
result.add(info);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开始检测下一个视频文件
|
||||
*/
|
||||
@@ -322,10 +313,6 @@ public class StreamDetector implements AutoCloseable{
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// if(isRunning){
|
||||
// System.out.println("--isRunning:" + isRunning);
|
||||
// stopDetection();
|
||||
// }
|
||||
if (grabberExecutor != null){
|
||||
grabberExecutor.shutdownNow();
|
||||
}
|
||||
@@ -345,15 +332,11 @@ public class StreamDetector implements AutoCloseable{
|
||||
private VideoSourceType sourceType = VideoSourceType.STREAM; // 默认流
|
||||
private int cameraIndex = 0; // 默认第一个摄像头
|
||||
|
||||
private long repeatGap = 5;//同物体重复检测间隔
|
||||
private boolean enableDebugLog; //是否开启debug log
|
||||
|
||||
public Builder detectorModel(DetectorModel m) { this.detectorModel = m; return this; }
|
||||
public Builder streamUrl(String url) { this.streamUrl = url; return this; }
|
||||
public Builder listener(StreamDetectionListener listener) { this.listener = listener; return this; }
|
||||
public Builder repeatGap(long repeatGap) {
|
||||
this.repeatGap = repeatGap;
|
||||
return this;
|
||||
}
|
||||
public Builder sourceType(VideoSourceType sourceType) {
|
||||
this.sourceType = sourceType;
|
||||
return this;
|
||||
@@ -368,6 +351,11 @@ public class StreamDetector implements AutoCloseable{
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder enableDebugLog(boolean enableDebugLog) {
|
||||
this.enableDebugLog = enableDebugLog;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StreamDetector build() {
|
||||
if (detectorModel == null) {
|
||||
throw new DetectionException("detectorModel 不能为空");
|
||||
|
||||
Reference in New Issue
Block a user