news 2026/4/2 10:08:51

DJL配合javacv实现视频车辆检测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DJL配合javacv实现视频车辆检测

1、pom文件

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>learndjl</artifactId> <version>1.0</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <djl.version>0.35.1</djl.version> <javacpp.platform.macosx-x86_64>macosx-x86_64</javacpp.platform.macosx-x86_64> <javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64> <javacpp.platform.windows-x86_64>windows-x86_64</javacpp.platform.windows-x86_64> <javacv.version>1.5.11</javacv.version> <javacv.ffmpeg.version>7.1-1.5.11</javacv.ffmpeg.version> <javacv.opencv.version>4.10.0-1.5.11</javacv.opencv.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>ai.djl</groupId> <artifactId>bom</artifactId> <version>${djl.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.9.0</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.17.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>2.24.1</version> </dependency> <dependency> <groupId>ai.djl</groupId> <artifactId>api</artifactId> </dependency> <dependency> <groupId>ai.djl</groupId> <artifactId>basicdataset</artifactId> </dependency> <dependency> <groupId>ai.djl</groupId> <artifactId>model-zoo</artifactId> </dependency> <dependency> <groupId>ai.djl.timeseries</groupId> <artifactId>timeseries</artifactId> </dependency> <dependency> <groupId>ai.djl.huggingface</groupId> <artifactId>tokenizers</artifactId> </dependency> <dependency> <groupId>ai.djl.audio</groupId> <artifactId>audio</artifactId> </dependency> <!-- MXNet --> <dependency> <groupId>ai.djl.mxnet</groupId> <artifactId>mxnet-model-zoo</artifactId> <scope>runtime</scope> </dependency> <!-- Pytorch --> <dependency> <groupId>ai.djl.pytorch</groupId> <artifactId>pytorch-model-zoo</artifactId> <scope>runtime</scope> </dependency> <!-- TensorFlow --> <dependency> <groupId>ai.djl.tensorflow</groupId> <artifactId>tensorflow-model-zoo</artifactId> <scope>runtime</scope> </dependency> <!-- ONNXRuntime --> <dependency> <groupId>ai.djl.onnxruntime</groupId> <artifactId>onnxruntime-engine</artifactId> <scope>runtime</scope> <exclusions> <exclusion> <groupId>com.microsoft.onnxruntime</groupId> <artifactId>onnxruntime</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.microsoft.onnxruntime</groupId> <artifactId>onnxruntime</artifactId> <version>1.20.0</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.10.2</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>${javacv.version}</version> </dependency> <!--javacv 精简依赖 只依赖windows64位ffmpeg--> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacpp</artifactId> <version>${javacv.version}</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg</artifactId> <version>${javacv.ffmpeg.version}</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/opencv-platform --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>opencv</artifactId> <version>4.10.0-1.5.11</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/tesseract --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>tesseract</artifactId> <version>5.5.0-1.5.11</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/openblas --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>openblas</artifactId> <version>0.3.28-1.5.11</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/leptonica --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>leptonica</artifactId> <version>1.85.0-1.5.11</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/flycapture --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>flycapture</artifactId> <version>2.13.3.31-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/libdc1394 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>libdc1394</artifactId> <version>2.2.6-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/libfreenect --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>libfreenect</artifactId> <version>0.5.7-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/libfreenect2 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>libfreenect2</artifactId> <version>0.2.0-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/librealsense --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>librealsense</artifactId> <version>1.12.4-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/librealsense2 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>librealsense2</artifactId> <version>2.53.1-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/videoinput --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>videoinput</artifactId> <version>0.200-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco/artoolkitplus --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>artoolkitplus</artifactId> <version>2.3.1-1.5.9</version> <classifier>${javacpp.platform.windows-x86_64}</classifier> </dependency> </dependencies> </project>

2、代码

package ai.djl.examples.inference.cv; import ai.djl.Application; import ai.djl.Device; import ai.djl.MalformedModelException; import ai.djl.inference.Predictor; import ai.djl.modality.cv.BufferedImageFactory; import ai.djl.modality.cv.Image; import ai.djl.modality.cv.output.DetectedObjects; import ai.djl.modality.cv.translator.YoloV5Translator; import ai.djl.modality.cv.translator.YoloV8TranslatorFactory; import ai.djl.repository.zoo.Criteria; import ai.djl.repository.zoo.ModelNotFoundException; import ai.djl.repository.zoo.ZooModel; import ai.djl.training.util.ProgressBar; import ai.djl.translate.TranslateException; import ai.djl.translate.Translator; import org.bytedeco.ffmpeg.global.avutil; import org.bytedeco.javacv.Java2DFrameUtils; import org.bytedeco.javacv.*; import org.bytedeco.opencv.opencv_core.Mat; import org.opencv.core.Core; import org.opencv.core.MatOfPoint; import org.opencv.core.Scalar; import org.opencv.imgproc.Imgproc; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Objects; public class Rtsp { /** * 原始RTSP流地址 */ private static final String RTSP = "rtmp://rtmp02open.ys7.com:1935/v3/openlive/33010243992887901197:33010927991327431255_1_1?expire=1765510803&id=919539092630331392&t=16f218c3c40b7b26d9ec84316603bf9a2dc7fa677969701585cda33709331889&ev=101&devProto=gb28181&supportH265=1"; /** * 模型路径 */ private static final String path = "D:\\LIHAOWORK\\models\\yolov5-pt\\model\\person\\person.onnx"; /** * 围栏多边形顶点 */ private static final org.opencv.core.Point[] points = {new org.opencv.core.Point(0, 300), new org.opencv.core.Point(350, 340), new org.opencv.core.Point(400, 500), new org.opencv.core.Point(0, 720),}; private static Predictor<Image, DetectedObjects> predictor; private static DetectedObjects result; private static float threshold = 0.2f; /** * 视频帧率 */ private static int frameRate = 30; /** * 视频帧宽度 */ private static int width = 640; /** * 视频帧高度 */ private static int height = 640; /** * 初始化 */ private static void init() { Criteria<Image, DetectedObjects> criteria = Criteria.builder() // 设置输入输出 .setTypes(Image.class, DetectedObjects.class) // .optModelUrls("djl://ai.djl.pytorch/yolo11n") .optModelUrls("https://mlrepo.djl.ai/model/cv/object_detection/ai/djl/onnxruntime/yolo11n/0.0.1/yolo11n.zip") .optEngine("OnnxRuntime") .optArgument("width", 640) .optArgument("height", 640) .optArgument("resize", true) .optArgument("toTensor", true) .optArgument("applyRatio", true) .optArgument("threshold", 0.6f) // for performance optimization maxBox parameter can reduce number of // considered boxes from 8400 .optArgument("maxBox", 1000) .optTranslatorFactory(new YoloV8TranslatorFactory()) // 进度条 .optProgress(new ProgressBar()) .build(); try { //模型加载 ZooModel<Image, DetectedObjects> model = criteria.loadModel(); predictor = model.newPredictor(); System.out.println("模型加载完成"); // System.loadLibrary(Core.NATIVE_LIBRARY_NAME); System.out.println("底层库加载完成"); } catch (IOException e) { e.printStackTrace(); } catch (ModelNotFoundException e) { e.printStackTrace(); } catch (MalformedModelException e) { e.printStackTrace(); } } public static void main(String[] args) { //开始抽帧 System.out.println("开始抽帧"); FFmpegFrameGrabber grabber = null; try { grabber = new FFmpegFrameGrabber("f:\\2020.mp4"); // grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式 // grabber.setOption("stimeout", "5000000"); grabber.setPixelFormat(avutil.AV_PIX_FMT_RGB24); // 像素格式 grabber.setImageWidth(width); grabber.setImageHeight(height); grabber.setFrameRate(frameRate); grabber.start(); //初始化模型 System.out.println("初始化模型"); init(); //播放窗口 System.out.println("播放窗口"); CanvasFrame canvasFrame = new CanvasFrame("摄像机"); canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); canvasFrame.setAlwaysOnTop(true); //核心处理逻辑 System.out.println("核心处理逻辑"); //初始化计数器为0 int i = 0; while (true) { //测试环境下无线循环 //抽取一帧 Frame frame = grabber.grabFrame(); if (frame == null) { continue; } //转换、推理、识别、绘制、转换 frame = processFrame(frame, i); if (Objects.isNull(frame)) { continue; } //展示 canvasFrame.showImage(frame); //计数器累加 i++; if (i >= frameRate) { //当计数器大于等于帧率时候重置为0 i = 0; } } } catch (Exception e) { e.printStackTrace(); } finally { } } /** * 推理 * * @param frame * @param i * @return */ private static Frame processFrame(Frame frame, int i) { System.out.println("1(frame2Image)"); Long start1 = System.currentTimeMillis(); Image image = frame2Image(frame); if (Objects.isNull(image)) { return null; } Long end1 = System.currentTimeMillis(); System.out.println("frame2Image耗时:" + (end1 - start1) + "ms"); //3帧推理一帧 if (i % 3 == 0) { try { System.out.println("2(推理)"); Long start2 = System.currentTimeMillis(); result = predictor.predict(image); Long end2 = System.currentTimeMillis(); System.out.println("推理耗时:" + (end2 - start2) + "ms"); } catch (TranslateException e) { e.printStackTrace(); } } System.out.println("3(结果)"); System.out.println(result); System.out.println("4(绘制)"); Long start3 = System.currentTimeMillis(); image.drawBoundingBoxes(result); Long end3 = System.currentTimeMillis(); System.out.println("绘制耗时:" + (end3 - start3) + "ms"); System.out.println("5(image2Frame)"); Long start4 = System.currentTimeMillis(); try { saveBoundingBoxImage(image, result, i); } catch (IOException e) { throw new RuntimeException(e); } Mat mat = image2Mat(image); Frame frameout = mat2Frame(mat); Long end4 = System.currentTimeMillis(); System.out.println("image2Frame耗时:" + (end4 - start4) + "ms"); return frameout; } /** * frame2Image * * @param frame * @return */ private static Image frame2Image(Frame frame) { BufferedImage temp = Java2DFrameUtils.toBufferedImage(frame); if (Objects.isNull(temp)) { return null; } Image image = BufferedImageFactory.getInstance().fromImage(temp); return image; } private static BufferedImage frame2BufferedImage(Frame frame) { BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(frame); return bufferedImage; } /** * image2Frame * * @param image * @return */ private static Frame image2Frame(Image image) { BufferedImage temp = (BufferedImage) image.getWrappedImage(); Frame frame = Java2DFrameUtils.toFrame(temp); return frame; } /** * image2Mat * * @param image * @return */ private static Mat image2Mat(Image image) { BufferedImage temp = (BufferedImage) image.getWrappedImage(); Mat mat = Java2DFrameUtils.toMat(temp); return mat; } /** * mat2Frame * * @param mat * @return */ private static Frame mat2Frame(Mat mat) { Frame frame = Java2DFrameUtils.toFrame(mat); return frame; } /** * 模拟绘制电子围栏 * * @param mat * @param points */ private static void drawRect(Mat mat, org.opencv.core.Point[] points) { OpenCVFrameConverter.ToMat converter1 = new OpenCVFrameConverter.ToMat(); OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat(); org.opencv.core.Mat cvmat = converter2.convert(converter1.convert(mat)); MatOfPoint ps = new MatOfPoint(); ps.fromArray(points); //Scalar 颜色 Scalar scalar = new Scalar(255, 0, 255); Imgproc.polylines(cvmat, Arrays.asList(ps), true, scalar, 5, Imgproc.LINE_8); } private static void saveBoundingBoxImage(Image img, DetectedObjects detection, int i) throws IOException { Path outputDir = Paths.get("build/output"); Files.createDirectories(outputDir); img.drawBoundingBoxes(detection); Path imagePath = outputDir.resolve("rtsp" + i + ".png"); // OpenJDK can't save jpg with alpha channel img.save(Files.newOutputStream(imagePath), "png"); } }

3、运行效果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 12:05:28

BL9342:1.8M,40V/600mA 降压DCDC稳压器

BL9342是一款高频异步降压开关稳压器&#xff0c;输入电压范围4.2~40V&#xff0c;最大输出电流600mA&#xff0c;固定1.8MHz开关频率&#xff0c;适用于高压电源转换、仪器、工业电源系统、分布式电源及电池供电系统等场景。采用6引脚SOT23-6封装&#xff0c;工作结温范围-40℃…

作者头像 李华
网站建设 2026/3/26 13:05:36

B端界面设计引导:别只做“说明书”,要当“效率助手”

B端引导设计的核心&#xff1a;让用户“一看就会&#xff0c;一用就爽”“这个按钮在哪&#xff1f;”“导出报表要点几步&#xff1f;”“数据异常怎么预警&#xff1f;”——很多B端产品上线后&#xff0c;总会收到诸如此类的反馈。问题根源并非用户“不愿学”&#xff0c;而…

作者头像 李华
网站建设 2026/4/2 2:54:09

论 Tick 数据 100% 完整性的生死意义

在量化交易领域&#xff0c;开发者精心构建的策略常因Tick 数据缺漏在实盘失效&#xff0c;根源并非逻辑缺陷&#xff0c;而是数据基础不稳。本文聚焦 Tick 数据 100% 完整性的核心价值&#xff0c;为量化交易开发者提供实用解决方案。 一、数据缺漏是量化交易 “隐形杀手” …

作者头像 李华
网站建设 2026/3/8 20:34:49

终于读懂了大模型、智能体、AIGC

关注我&#xff0c;不迷路 今天给小伙伴们分享一下。 一、大模型概念 1.1 大模型通常指的是大规模的人工智能模型&#xff0c;是一种基于深度学习技术&#xff0c;具有海量参数、强大的学习能力和泛化能力&#xff0c;能够处理和生成多种类型数据的人工智能模型。 通常说的大模…

作者头像 李华
网站建设 2026/4/2 13:04:19

16种大模型主流微调方法

大语言模型&#xff08;LLM&#xff09;的微调是让通用模型适应特定任务的关键技术。本文将系统介绍16种主流微调方法&#xff0c;帮助你根据实际需求选择合适的技术方案。 一、参数高效微调&#xff08;Parameter-Efficient Fine-Tuning, PEFT&#xff09; 这类方法的核心思想…

作者头像 李华