diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite index 3c9303c..032f49a 100644 Binary files a/.vs/slnx.sqlite and b/.vs/slnx.sqlite differ diff --git a/src/main/java/com/bonus/sdk/YoloSdk.java b/src/main/java/com/bonus/sdk/YoloSdk.java index 4a077ac..9e2ab2c 100644 --- a/src/main/java/com/bonus/sdk/YoloSdk.java +++ b/src/main/java/com/bonus/sdk/YoloSdk.java @@ -11,21 +11,15 @@ import java.util.Set; public class YoloSdk implements AutoCloseable { - private long nativeHandle; // 指向 C++ YoloDetector 实例的指针 + private long nativeHandle; private static final Set loadedLibraries = new HashSet<>(); - private static Path tempDir; // 用于存放所有本地库的唯一临时目录 + private static Path tempDir; + - /** - * 静态初始化块,用于加载本地库。 - */ static { try { - // 1. 创建一个唯一的临时目录,用于存放所有DLL/SO文件 tempDir = Files.createTempDirectory("yolo_sdk_native_libs_"); - // 2. 确保在JVM退出时删除此目录 tempDir.toFile().deleteOnExit(); - - // 3. 将所有库解压并加载到此目录 loadSdkLibrary(tempDir); } catch (IOException e) { @@ -33,10 +27,6 @@ public class YoloSdk implements AutoCloseable { } } - /** - * 负责解压和加载所有本地库。 - * @param tempDir - */ private static void loadSdkLibrary(Path tempDir) throws IOException { String osName = System.getProperty("os.name").toLowerCase(); String osArch = System.getProperty("os.arch").toLowerCase(); @@ -46,7 +36,6 @@ public class YoloSdk implements AutoCloseable { if (osName.contains("win") && osArch.contains("64")) { libPathInJar = "/lib/win-x64/"; - // 依赖项必须按加载顺序列出 dependencyLibs = new String[]{ "abseil_dll.dll", "libprotobuf.dll", @@ -61,9 +50,8 @@ public class YoloSdk implements AutoCloseable { } else if ((osName.contains("nix") || osName.contains("nux")) && osArch.contains("64")) { libPathInJar = "/lib/linux-x86_64/"; - // 确保这些是您Linux构建所需的 .so 依赖项 dependencyLibs = new String[]{ - "libonnxruntime.so.1.23.2", // 示例,请使用您确切的文件名 + "libonnxruntime.so.1.23.2", "libopencv_core.so.4.6.0", "libopencv_imgproc.so.4.6.0", "libopencv_dnn.so.4.6.0" @@ -74,17 +62,11 @@ public class YoloSdk implements AutoCloseable { throw new UnsupportedOperationException("Unsupported OS/Arch: " + osName + "/" + osArch); } - // --- 关键的修复逻辑 --- - - // 步骤 1: 首先,将所有库文件从JAR解压到同一个临时目录,保持原始文件名 for (String lib : dependencyLibs) { extractLibraryFromJar(libPathInJar + lib, tempDir); } - // 解压主SDK库 extractLibraryFromJar(libPathInJar + sdkLibName, tempDir); - // 步骤 2: 然后,按顺序从该临时目录加载库 - // 这样,Windows/Linux加载器可以在同一目录中找到所有依赖项 try { for (String lib : dependencyLibs) { if (!loadedLibraries.contains(lib)) { @@ -97,20 +79,14 @@ public class YoloSdk implements AutoCloseable { loadedLibraries.add(sdkLibName); } } catch (UnsatisfiedLinkError e) { - // 提供更详细的错误信息 System.err.println("--- NATIVE LIBRARY LOAD FAILED ---"); System.err.println("Failed to load native library. This often means a dependency is missing on the host system."); System.err.println("For Windows: Ensure 'Visual C++ Redistributable for Visual Studio (x64)' is installed."); System.err.println("Libraries were extracted to: " + tempDir.toAbsolutePath()); System.err.println("-----------------------------------"); - throw e; // 重新抛出原始错误 + throw e; } } - - /** - * * @param pathInJar - * @param tempDir - */ private static void extractLibraryFromJar(String pathInJar, Path tempDir) throws IOException { String libName = new File(pathInJar).getName(); @@ -119,18 +95,14 @@ public class YoloSdk implements AutoCloseable { throw new FileNotFoundException("Library " + pathInJar + " not found in JAR."); } - // 目标文件路径,保持原始文件名 Path targetFile = tempDir.resolve(libName); - // 将文件从JAR复制到临时目录 Files.copy(in, targetFile, StandardCopyOption.REPLACE_EXISTING); - // 为解压的目录/文件设置退出时删除(双重保险) targetFile.toFile().deleteOnExit(); } } - // --- Native JNI 方法 --- private native long nativeInit(String modelPath, int inputWidth, int inputHeight); private native void nativeRelease(long handle); private native Detection[] nativePredict( @@ -138,10 +110,7 @@ public class YoloSdk implements AutoCloseable { float confThreshold, float iouThreshold ); - // --- 公共 Java API --- - /** - * 初始化YOLO SDK。 * @param modelPath * @param inputWidth * @param inputHeight @@ -170,9 +139,6 @@ public class YoloSdk implements AutoCloseable { ); } - /** - * 释放本地资源。 - */ @Override public void close() { if (this.nativeHandle != 0) { @@ -182,16 +148,14 @@ public class YoloSdk implements AutoCloseable { } /** - * * @param image + * @param image * @return */ private byte[] getBgrBytes(BufferedImage image) { - // 如果图像已经是 3-byte BGR,直接返回 if (image.getType() == BufferedImage.TYPE_3BYTE_BGR) { return ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); } - // 否则,创建一个 BGR 副本 BufferedImage bgrImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); bgrImage.getGraphics().drawImage(image, 0, 0, null); return ((DataBufferByte) bgrImage.getRaster().getDataBuffer()).getData(); diff --git a/test_data/model.onnx b/test_data/model.onnx index 66aacff..e83238f 100644 Binary files a/test_data/model.onnx and b/test_data/model.onnx differ diff --git a/test_data/model_bak.onnx b/test_data/model_bak.onnx new file mode 100644 index 0000000..66aacff Binary files /dev/null and b/test_data/model_bak.onnx differ