pom.xml 文件中需要增加一些包。

<repositories>
        <repository>
            <id>opencv</id>
            <url>https://mvnrepository.com/artifact/org.openpnp/opencv</url>
        </repository>
        <repository>
            <id>djl.ai</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        </repository>
</repositories>
<dependencies>
  <!-- DJL Core API -->
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>api</artifactId>
            <version>${djl.version}</version>
        </dependency>

        <!-- DJL PyTorch Engine -->
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-engine</artifactId>
            <version>${djl.version}</version>
        </dependency>

        <!-- DJL PyTorch Model Zoo -->
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-model-zoo</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <!-- DJL Basic Dataset -->
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>basicdataset</artifactId>
            <version>${djl.version}</version>
        </dependency>

        <!-- DJL Image Processing -->
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>basicdataset</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openpnp/opencv -->
        <dependency>
            <groupId>org.openpnp</groupId>
            <artifactId>opencv</artifactId>
            <version>4.9.0-0</version>
        </dependency>
</dependencies>

Java 中缺少一些追踪算法,无法在视频中追踪物体,达到视频计数的目的,只能够按帧进行标记。

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class YOLOv8Util {

    public static Map<String, Integer> runScript(String pythonInterpreter, String scriptPath, String workingDirectory, String source, boolean viewImg, boolean saveImg, List<String> classes, String weights) throws IOException, InterruptedException {
        List<String> command = buildCommand(pythonInterpreter, scriptPath, source, viewImg, saveImg, classes, weights);

        ProcessBuilder pb = new ProcessBuilder(command);
        pb.directory(new File(workingDirectory)); // 设置工作目录
        Process process = pb.start();
        String lastJsonOutput = null;
        // 获取脚本的标准输出
        try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
             BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {

            // 读取标准输出
            String line;
            while ((line = stdInput.readLine()) != null) {
                lastJsonOutput = line.trim();
                System.out.println("Standard Output: " + line);
            }

            // 读取错误输出
            while ((line = stdError.readLine()) != null) {
                System.err.println("Error Output: " + line);
            }
        }

        // 等待脚本执行完毕
//        int exitCode = process.waitFor();
//        System.out.println("Exited with code : " + exitCode);

        // 如果有 JSON 输出,则解析为 Map
        if (lastJsonOutput != null) {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(lastJsonOutput, Map.class);
        } else {
            throw new IOException("No JSON output received from the Python script.");
        }

    }

    // https://github.com/ultralytics/ultralytics/blob/main/examples/YOLOv8-Region-Counter/readme.md
    private static List<String> buildCommand(String pythonInterpreter, String scriptPath, String source, boolean viewImg, boolean saveImg, List<String> classes, String weights) {
        List<String> command = new ArrayList<>();
        command.add(pythonInterpreter);
        command.add(scriptPath);
        command.add("--source");
        command.add(source);
//        if (viewImg) {
//            command.add("--view-img");
//        }
//        if (saveImg) {
//            command.add("--save-img");
//        }
        command.add("--device");
        command.add("cpu");
        command.add("--classes");
        command.addAll(classes);  // 添加多个类索引
        command.add("--weights");
        command.add(weights);
        return command;
    }

    public static void main(String[] args) {
        String pythonInterpreter = "/Users/luciuschen/YOLO/bin/python3";
        String scriptPath = "/Users/luciuschen/YOLO/yolov8-video.py";
        String workingDirectory = "/Users/luciuschen/YOLO/";

        // 创建一个固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(4);
        ClassLoader classLoader = Main.class.getClassLoader();
        URL resource = classLoader.getResource("script/best.pt");
        Path path = Paths.get(resource.getPath());

        try {
            // 提交任务给线程池并获取 Future 对象
            Future<Map<String, Integer>> future =  executor.submit(new PythonScriptRunnerTask(pythonInterpreter, scriptPath, workingDirectory, "/Users/luciuschen/YOLO/test.mp4", true, true, Arrays.asList("0", "2"), path.toString()));

            // 获取任务的执行结果
            Map<String, Integer> resultMap = future.get();
            System.out.println("Result Map: " + resultMap);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭线程池
            executor.shutdown();
        }
    }
}

class PythonScriptRunnerTask implements Callable<Map<String, Integer>> {
    private final String pythonInterpreter;
    private final String scriptPath;
    private final String workingDirectory;
    private final String source;
    private final boolean viewImg;
    private final boolean saveImg;
    private final List<String> classes;
    private final String weights;

    public PythonScriptRunnerTask(String pythonInterpreter, String scriptPath, String workingDirectory, String source, boolean viewImg, boolean saveImg, List<String> classes, String weights) {
        this.pythonInterpreter = pythonInterpreter;
        this.scriptPath = scriptPath;
        this.workingDirectory = workingDirectory;
        this.source = source;
        this.viewImg = viewImg;
        this.saveImg = saveImg;
        this.classes = classes;
        this.weights = weights;
    }

    @Override
    public Map call() throws Exception {
        return YOLOv8Util.runScript(pythonInterpreter, scriptPath, workingDirectory, source, viewImg, saveImg, classes, weights);
    }
}

No notes link to this note