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