当前位置: 首页 > news >正文

Java 实现 YoloV7 人体姿态识别

1 OpenCV 环境的准备

这个项目中需要用到 opencv 进行图片的读取与处理操作,因此我们需要先配置一下 opencv 在 java 中运行的配置。

首先前往 opencv 官网下载 opencv-4.6 :点此下载;下载好后仅选择路径后即可完成安装。

此时将 opencv\build\java\x64 路径下的 opencv_java460.dll 复制到 C:\Windows\System32 中,再将 D:\Tools\opencv\opencv\build\java 下的 opencv-460.jar 放到我们 Springboot 项目 resources 文件夹下的 lib 文件夹下。

本文所需 ONNX 文件请 点此下载 。

JAVA使用YOLOV7进行 目标检测 请转至 Java使用OnnxRuntime及OpenCV实现YoloV7目标检测,
项目代码可前往 项目主页 查看。

2 Maven 配置

引入 onnxruntime 和 opencv 这两个依赖即可。值得注意的是,引 opencv 时systemPath记得与上文说的opencv-460.jar所在路径保持一致。

<dependency><groupId>com.microsoft.onnxruntime</groupId><artifactId>onnxruntime</artifactId><version>1.12.1</version>
</dependency><dependency><groupId>org.opencv</groupId><artifactId>opencv</artifactId><version>4.6.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/opencv-460.jar</systemPath>
</dependency>

3 Config

3.1 PEPlotConfig.java

在此配置一些画图时用到的超参数

package cn.halashuo.config;import org.opencv.core.Scalar;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public final class PEPlotConfig {public static final List<Scalar> palette= new ArrayList<>(Arrays.asList(new Scalar( 255, 128, 0 ),new Scalar( 255, 153, 51 ),new Scalar( 255, 178, 102 ),new Scalar( 230, 230, 0 ),new Scalar( 255, 153, 255 ),new Scalar( 153, 204, 255 ),new Scalar( 255, 102, 255 ),new Scalar( 255, 51, 255 ),new Scalar( 102, 178, 255 ),new Scalar( 51, 153, 255 ),new Scalar( 255, 153, 153 ),new Scalar( 255, 102, 102 ),new Scalar( 255, 51, 51 ),new Scalar( 153, 255, 153 ),new Scalar( 102, 255, 102 ),new Scalar( 51, 255, 51 ),new Scalar( 0, 255, 0 ),new Scalar( 0, 0, 255 ),new Scalar( 255, 0, 0 ),new Scalar( 255, 255, 255 )));public static final int[][] skeleton = {{16, 14}, {14, 12}, {17, 15}, {15, 13}, {12, 13}, {6, 12},{7, 13}, {6, 7}, {6, 8}, {7, 9}, {8, 10}, {9, 11}, {2, 3},{1, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}};public static final List<Scalar> poseLimbColor = new ArrayList<>(Arrays.asList(palette.get(9), palette.get(9), palette.get(9), palette.get(9), palette.get(7),palette.get(7), palette.get(7), palette.get(0), palette.get(0), palette.get(0),palette.get(0), palette.get(0), palette.get(16), palette.get(16), palette.get(16),palette.get(16), palette.get(16), palette.get(16), palette.get(16)));public static final List<Scalar> poseKptColor = new ArrayList<>(Arrays.asList(palette.get(16), palette.get(16), palette.get(16), palette.get(16), palette.get(16),palette.get(0), palette.get(0), palette.get(0), palette.get(0), palette.get(0),palette.get(0), palette.get(9), palette.get(9), palette.get(9), palette.get(9),palette.get(9), palette.get(9)));}

4 Utils

3.1 Letterbox.java

这个类负责调整图像大小和填充图像,使满足步长约束,并记录参数。

package cn.halashuo.utils;import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;public class Letterbox {private final Size newShape = new Size(1280, 1280);private final double[] color = new double[]{114,114,114};private final Boolean auto = false;private final Boolean scaleUp = true;private final Integer stride = 32;private double ratio;private double dw;private double dh;public double getRatio() {return ratio;}public double getDw() {return dw;}public Integer getWidth() {return (int) this.newShape.width;}public Integer getHeight() {return (int) this.newShape.height;}public double getDh() {return dh;}public Mat letterbox(Mat im) { // 调整图像大小和填充图像,使满足步长约束,并记录参数int[] shape = {im.rows(), im.cols()}; // 当前形状 [height, width]// Scale ratio (new / old)double r = Math.min(this.newShape.height / shape[0], this.newShape.width / shape[1]);if (!this.scaleUp) { // 仅缩小,不扩大(一起为了mAP)r = Math.min(r, 1.0);}// Compute paddingSize newUnpad = new Size(Math.round(shape[1] * r), Math.round(shape[0] * r));double dw = this.newShape.width - newUnpad.width, dh = this.newShape.height - newUnpad.height; // wh 填充if (this.auto) { // 最小矩形dw = dw % this.stride;dh = dh % this.stride;}dw /= 2; // 填充的时候两边都填充一半,使图像居于中心dh /= 2;if (shape[1] != newUnpad.width || shape[0] != newUnpad.height) { // resizeImgproc.resize(im, im, newUnpad, 0, 0, Imgproc.INTER_LINEAR);}int top = (int) Math.round(dh - 0.1), bottom = (int) Math.round(dh + 0.1);int left = (int) Math.round(dw - 0.1), right = (int) Math.round(dw + 0.1);// 将图像填充为正方形Core.copyMakeBorder(im, im, top, bottom, left, right, Core.BORDER_CONSTANT, new org.opencv.core.Scalar(this.color));this.ratio = r;this.dh = dh;this.dw = dw;return im;}
}

3.2 NMS.java

这个类负责进行非极大值抑制,以筛选检测到的人。

package cn.halashuo.utils;import cn.halashuo.domain.PEResult;import java.util.ArrayList;
import java.util.List;public class NMS {public static List<PEResult> nms(List<PEResult> boxes, float iouThreshold) {// 根据score从大到小对List进行排序boxes.sort((b1, b2) -> Float.compare(b2.getScore(), b1.getScore()));List<PEResult> resultList = new ArrayList<>();for (int i = 0; i < boxes.size(); i++) {PEResult box = boxes.get(i);boolean keep = true;// 从i+1开始,遍历之后的所有boxes,移除与box的IOU大于阈值的元素for (int j = i + 1; j < boxes.size(); j++) {PEResult otherBox = boxes.get(j);float iou = getIntersectionOverUnion(box, otherBox);if (iou > iouThreshold) {keep = false;break;}}if (keep) {resultList.add(box);}}return resultList;}private static float getIntersectionOverUnion(PEResult box1, PEResult box2) {float x1 = Math.max(box1.getX0(), box2.getX0());float y1 = Math.max(box1.getY0(), box2.getY0());float x2 = Math.min(box1.getX1(), box2.getX1());float y2 = Math.min(box1.getY1(), box2.getY1());float intersectionArea = Math.max(0, x2 - x1) * Math.max(0, y2 - y1);float box1Area = (box1.getX1() - box1.getX0()) * (box1.getY1() - box1.getY0());float box2Area = (box2.getX1() - box2.getX0()) * (box2.getY1() - box2.getY0());float unionArea = box1Area + box2Area - intersectionArea;return intersectionArea / unionArea;}
}

5 domain

5.1 KeyPoint.java

记录关键点信息的实体类。

package cn.halashuo.domain;public class KeyPoint {private Integer id;private Float x;private Float y;private Float score;public KeyPoint(Integer id, Float x, Float y, Float score) {this.id = id;this.x = x;this.y = y;this.score = score;}public Integer getId() {return id;}public Float getX() {return x;}public Float getY() {return y;}public Float getScore() {return score;}@Overridepublic String toString() {return "    第 " + (id+1) + " 个关键点: " +" x=" + x +" y=" + y +" c=" + score +"\n";}
}

5.2 PEResult.java

记录所有人物检测信息的实体类。

package cn.halashuo.domain;import java.util.ArrayList;
import java.util.List;public class PEResult {private Float x0;private Float y0;private Float x1;private Float y1;private Float score;private Integer clsId;private List<KeyPoint> keyPointList;public PEResult(float[] peResult) {float x = peResult[0];float y = peResult[1];float w = peResult[2]/2.0f;float h = peResult[3]/2.0f;this.x0 = x-w;this.y0 = y-h;this.x1 = x+w;this.y1 = y+h;this.score = peResult[4];this.clsId = (int) peResult[5];this.keyPointList = new ArrayList<>();int keyPointNum = (peResult.length-6)/3;for (int i=0;i<keyPointNum;i++) {this.keyPointList.add(new KeyPoint(i, peResult[6+3*i], peResult[6+3*i+1], peResult[6+3*i+2]));}}public Float getX0() {return x0;}public Float getY0() {return y0;}public Float getX1() {return x1;}public Float getY1() {return y1;}public Float getScore() {return score;}public Integer getClsId() {return clsId;}public List<KeyPoint> getKeyPointList() {return keyPointList;}@Overridepublic String toString() {String result = "PEResult:" +"  x0=" + x0 +", y0=" + y0 +", x1=" + x1 +", y1=" + y1 +", score=" + score +", clsId=" + clsId +"\n";for (KeyPoint x : keyPointList) {result = result + x.toString();}return result;}
}

6 PoseEstimation.java

设置好 ONNX 文件路径及需要识别的图片路径即可。如有需要也可设置 CUDA 作为运行环境,大幅提升 FPS。

package cn.halashuo;import ai.onnxruntime.OnnxTensor;
import ai.onnxruntime.OrtEnvironment;
import ai.onnxruntime.OrtException;
import ai.onnxruntime.OrtSession;
import cn.halashuo.domain.KeyPoint;
import cn.halashuo.domain.PEResult;
import cn.halashuo.utils.Letterbox;
import cn.halashuo.utils.NMS;
import cn.halashuo.config.PEPlotConfig;
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;public class PoseEstimation {static{//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static void main(String[] args) throws OrtException {// 加载ONNX模型OrtEnvironment environment = OrtEnvironment.getEnvironment();OrtSession.SessionOptions sessionOptions = new OrtSession.SessionOptions();OrtSession session = environment.createSession("src\\main\\resources\\model\\yolov7-w6-pose.onnx", sessionOptions);// 输出基本信息session.getInputInfo().keySet().forEach(x -> {try {System.out.println("input name = " + x);System.out.println(session.getInputInfo().get(x).getInfo().toString());} catch (OrtException e) {throw new RuntimeException(e);}});// 读取 imageMat img = Imgcodecs.imread("src\\main\\resources\\image\\bus.jpg");Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB);Mat image = img.clone();// 在这里先定义下线的粗细、关键的半径(按比例设置大小粗细比较好一些)int minDwDh = Math.min(img.width(), img.height());int thickness = minDwDh / 333;int radius = minDwDh / 168;// 更改 image 尺寸Letterbox letterbox = new Letterbox();letterbox.setNewShape(new Size(960, 960));letterbox.setStride(64);image = letterbox.letterbox(image);double ratio = letterbox.getRatio();double dw = letterbox.getDw();double dh = letterbox.getDh();int rows = letterbox.getHeight();int cols = letterbox.getWidth();int channels = image.channels();// 将Mat对象的像素值赋值给Float[]对象float[] pixels = new float[channels * rows * cols];for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {double[] pixel = image.get(j, i);for (int k = 0; k < channels; k++) {// 这样设置相当于同时做了image.transpose((2, 0, 1))操作pixels[rows * cols * k + j * cols + i] = (float) pixel[k] / 255.0f;}}}// 创建OnnxTensor对象long[] shape = {1L, (long) channels, (long) rows, (long) cols};OnnxTensor tensor = OnnxTensor.createTensor(environment, FloatBuffer.wrap(pixels), shape);HashMap<String, OnnxTensor> stringOnnxTensorHashMap = new HashMap<>();stringOnnxTensorHashMap.put(session.getInputInfo().keySet().iterator().next(), tensor);// 运行模型OrtSession.Result output = session.run(stringOnnxTensorHashMap);// 得到结果float[][] outputData = ((float[][][]) output.get(0).getValue())[0];List<PEResult> peResults = new ArrayList<>();for (int i=0;i<outputData.length;i++){PEResult result = new PEResult(outputData[i]);if (result.getScore()>0.25f) {peResults.add(result);}}// 对结果进行非极大值抑制peResults = NMS.nms(peResults, 0.65f);for (PEResult peResult: peResults) {System.out.println(peResult);// 画框Point topLeft = new Point((peResult.getX0()-dw)/ratio, (peResult.getY0()-dh)/ratio);Point bottomRight = new Point((peResult.getX1()-dw)/ratio, (peResult.getY1()-dh)/ratio);Imgproc.rectangle(img, topLeft, bottomRight, new Scalar(255,0,0), thickness);List<KeyPoint> keyPoints = peResult.getKeyPointList();// 画点keyPoints.forEach(keyPoint->{if (keyPoint.getScore()>0.50f) {Point center = new Point((keyPoint.getX()-dw)/ratio, (keyPoint.getY()-dh)/ratio);Scalar color = PEPlotConfig.poseKptColor.get(keyPoint.getId());Imgproc.circle(img, center, radius, color, -1); //-1表示实心}});// 画线for (int i=0;i<PEPlotConfig.skeleton.length;i++){int indexPoint1 = PEPlotConfig.skeleton[i][0]-1;int indexPoint2 = PEPlotConfig.skeleton[i][1]-1;if ( keyPoints.get(indexPoint1).getScore()>0.5f && keyPoints.get(indexPoint2).getScore()>0.5f ) {Scalar coler = PEPlotConfig.poseLimbColor.get(i);Point point1 = new Point((keyPoints.get(indexPoint1).getX()-dw)/ratio,(keyPoints.get(indexPoint1).getY()-dh)/ratio);Point point2 = new Point((keyPoints.get(indexPoint2).getX()-dw)/ratio,(keyPoints.get(indexPoint2).getY()-dh)/ratio);Imgproc.line(img, point1, point2, coler, thickness);}}}Imgproc.cvtColor(img, img, Imgproc.COLOR_RGB2BGR);// 保存图像// Imgcodecs.imwrite("image.jpg", img);HighGui.imshow("Display Image", img);// 等待按下任意键继续执行程序HighGui.waitKey();}
}

运行结果:

input name = images
TensorInfo(javaType=FLOAT,onnxType=ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,shape=[1, 3, 960, 960])
PEResult:  x0=164.1142, y0=357.69672, x1=341.0573, y1=800.42975, score=0.7534131, clsId=0第 1 个关键点:  x=246.95715 y=397.0772 c=0.9736327第 2 个关键点:  x=252.17633 y=389.2904 c=0.8335564第 3 个关键点:  x=238.11848 y=389.0014 c=0.96936846第 4 个关键点:  x=256.3179 y=395.70413 c=0.26490688第 5 个关键点:  x=217.58188 y=395.21817 c=0.9350542第 6 个关键点:  x=261.88034 y=443.02286 c=0.9898272第 7 个关键点:  x=197.16116 y=444.8831 c=0.9871879第 8 个关键点:  x=288.0304 y=506.67032 c=0.96026266第 9 个关键点:  x=232.06883 y=506.9636 c=0.97538215第 10 个关键点:  x=239.84201 y=521.9722 c=0.9516981第 11 个关键点:  x=277.70163 y=489.83765 c=0.970703第 12 个关键点:  x=257.0904 y=574.55255 c=0.9929459第 13 个关键点:  x=208.6877 y=576.3064 c=0.9918982第 14 个关键点:  x=271.411 y=667.6743 c=0.98325074第 15 个关键点:  x=203.27112 y=671.0604 c=0.98317075第 16 个关键点:  x=285.6367 y=760.895 c=0.91636044第 17 个关键点:  x=184.19543 y=757.7814 c=0.91179585PEResult:  x0=316.40674, y0=360.82706, x1=426.57, y1=759.98706, score=0.2713838, clsId=0第 1 个关键点:  x=381.07776 y=401.219 c=0.97289705第 2 个关键点:  x=386.32465 y=393.87543 c=0.8813406第 3 个关键点:  x=372.7825 y=394.40253 c=0.9677005第 4 个关键点:  x=392.475 y=397.61212 c=0.38852227第 5 个关键点:  x=358.659 y=399.40833 c=0.90877795第 6 个关键点:  x=402.89664 y=442.8764 c=0.9850693第 7 个关键点:  x=344.9049 y=448.23697 c=0.98851293第 8 个关键点:  x=414.33658 y=491.29187 c=0.932391第 9 个关键点:  x=342.81982 y=514.2552 c=0.97218585第 10 个关键点:  x=372.42307 y=471.12778 c=0.9217508第 11 个关键点:  x=355.56168 y=568.59796 c=0.9616347第 12 个关键点:  x=395.88492 y=558.541 c=0.98994935第 13 个关键点:  x=356.53287 y=560.3552 c=0.99083第 14 个关键点:  x=402.41013 y=636.82916 c=0.97681665第 15 个关键点:  x=356.1795 y=645.22626 c=0.9832493第 16 个关键点:  x=363.65356 y=694.9054 c=0.92282534第 17 个关键点:  x=358.54623 y=727.66455 c=0.93670356PEResult:  x0=120.30354, y0=488.97424, x1=189.55516, y1=765.24194, score=0.2625065, clsId=0第 1 个关键点:  x=128.37527 y=496.36432 c=0.039970636第 2 个关键点:  x=129.2826 y=488.29858 c=0.01759991第 3 个关键点:  x=129.88588 y=487.7059 c=0.023388624第 4 个关键点:  x=128.1956 y=486.87085 c=0.022539705第 5 个关键点:  x=129.61555 y=486.93362 c=0.026325405第 6 个关键点:  x=124.60656 y=506.1516 c=0.11605239第 7 个关键点:  x=124.11076 y=506.29758 c=0.1002911第 8 个关键点:  x=129.53989 y=577.0432 c=0.39045402第 9 个关键点:  x=129.05757 y=578.36163 c=0.4030531第 10 个关键点:  x=161.94182 y=651.2286 c=0.51389414第 11 个关键点:  x=162.66849 y=654.58966 c=0.54413426第 12 个关键点:  x=128.37022 y=633.2864 c=0.12599188第 13 个关键点:  x=128.395 y=635.9184 c=0.110325515第 14 个关键点:  x=128.9154 y=668.3744 c=0.098092705第 15 个关键点:  x=129.4807 y=669.07947 c=0.08956778第 16 个关键点:  x=128.86487 y=750.24927 c=0.09377599第 17 个关键点:  x=127.63382 y=751.3636 c=0.086484134PEResult:  x0=710.87134, y0=352.32605, x1=839.29944, y1=781.6887, score=0.2580245, clsId=0第 1 个关键点:  x=815.21063 y=390.9094 c=0.37949353第 2 个关键点:  x=819.77454 y=382.87204 c=0.34996593第 3 个关键点:  x=816.6579 y=382.68045 c=0.0947094第 4 个关键点:  x=831.6544 y=386.69308 c=0.3775956第 5 个关键点:  x=830.4774 y=386.01678 c=0.044245332第 6 个关键点:  x=828.6047 y=435.97873 c=0.62260723第 7 个关键点:  x=838.1829 y=433.01996 c=0.32877648第 8 个关键点:  x=817.08154 y=511.3317 c=0.7232578第 9 个关键点:  x=824.0419 y=505.8941 c=0.21007198第 10 个关键点:  x=773.95953 y=496.15784 c=0.80840695第 11 个关键点:  x=790.11487 y=490.05597 c=0.33966026第 12 个关键点:  x=826.98004 y=571.4592 c=0.6694445第 13 个关键点:  x=830.14514 y=567.2725 c=0.508251第 14 个关键点:  x=796.26184 y=655.2373 c=0.81898046第 15 个关键点:  x=802.0529 y=650.5082 c=0.6584172第 16 个关键点:  x=762.1977 y=747.01917 c=0.6550461第 17 个关键点:  x=763.58057 y=741.5452 c=0.5072014

使用 yolov7-w6-pose 的官方模型训练并转化成 onnx 后,得到的结果维度为 n × 57 n\times 57 n×57。其中,前六个元素分别是 x、y、w、h、score、classId。关键点信息由x、y、score三个元素构成,共有17个关键点,因此每个人体监测信息共计 3 × 17 + 6 = 57 3\times 17 + 6 = 57 3×17+6=57 个元素。

相关文章:

Java 实现 YoloV7 人体姿态识别

1 OpenCV 环境的准备 这个项目中需要用到 opencv 进行图片的读取与处理操作&#xff0c;因此我们需要先配置一下 opencv 在 java 中运行的配置。 首先前往 opencv 官网下载 opencv-4.6 &#xff1a;点此下载&#xff1b;下载好后仅选择路径后即可完成安装。 此时将 opencv\b…...

跨越屏幕:桌面PC端的多端开发框架介绍

目前&#xff0c;随着互联网和移动互联网的发展&#xff0c;多端开发框架已经成为越来越多开发者更好的选择。主要有以下几个方面的前景&#xff1a; 跨平台开发需求不断增加&#xff1a;由于不同平台和设备的差异性&#xff0c;开发人员需要使用不同的编程语言和开发工具来为各…...

高效学习方法和工具推荐,让你事半功倍!

本文介绍了五种高效学习方法&#xff0c;包括制定详细的学习计划、集中注意力、不断复习、采用多种学习方式和利用小休息。同时&#xff0c;还推荐了五个高效学习工具和平台&#xff0c;包括Coursera、Duolingo、Quizlet、Khan Academy和Anki&#xff0c;让你在学习中事半功倍&…...

查看Docker容器中RabbitMQ的密码

要查看Docker容器中RabbitMQ的密码&#xff0c;可以尝试以下几个步骤&#xff1a; 1. 查看容器运行时的环境变量 在Docker容器中&#xff0c;可以通过环境变量来设置RabbitMQ的用户名和密码。因此&#xff0c;可以使用以下命令查看容器的环境变量&#xff1a; docker inspect…...

探索Qt线程编程的奥秘:多角度深入剖析

探索Qt线程编程的奥秘&#xff1a;多角度深入剖析 一、Qt线程编程基础&#xff08;Qt Threading Basics&#xff09;1.1 线程概念与基本概念&#xff08;Thread Concepts and Fundamentals&#xff09;1.2 Qt线程类简介&#xff1a;QThread&#xff08;Introduction to Qt Thre…...

【R语言】鉴于计算10亿以内训练模型记录for循环的加速

文章目录 1 前言2 几个循环2.1 100以内的和2.2 100以内奇数和/偶数和 3 多重循环3.1 向量化3.2 合并循环3.3 apply函数3.4 矩阵运算3.5 foreach分解任务 4 讨论 1 前言 笔者主力机是MBAM1芯片&#xff08;8256&#xff09;&#xff0c;某个下午巩固循环突然思考到个问题&#…...

C++类和对象 ——构造函数

C拷贝构造函数详解 什么是拷贝构造函数&#xff1f;拷贝构造函数的特征默认拷贝构造函数为什么需要显示定义构造函数&#xff1f;拷贝构造函数的调用场景什么时候不需要自己定义拷贝构造函数 什么是拷贝构造函数&#xff1f; 在现实生活中&#xff0c;拷贝构造函数就好像我们上…...

第2章-分治法

第2章-分治法 总分&#xff1a;100分 得分&#xff1a;20.0分 1 . 多选题 中等 10分 有关以下代码&#xff0c;说法正确的是&#xff08; ABCE&#xff09; def BinarySearch(s, x, low, high):if (low > high):return -1middle (low high) / 2if (x s[mid…...

20天能拿下PMP吗?

新版大纲&#xff0c;专注于人员、过程、业务环境三个领域&#xff0c;内容贯穿价值交付范围&#xff08;包括预测、敏捷和混合的方法&#xff09;。除了考试时间由240分钟变更为230分钟、200道单选题变为180道&#xff08;包含单选和多选&#xff09;之外&#xff0c;新考纲还…...

Word处理控件Aspose.Words功能演示:在 Java 中将 Word DOC/DOCX 转换为 PDF

Aspose.Words是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。 Aspose API支持流行文件格式处理&#xff0c;并…...

数据安全的重要性

数据安全非常重要&#xff0c;因为我们生活在数字化时代&#xff0c;许多信息和数据都以数字形式存储和传输。如果这些数据受到未经授权的访问、篡改、泄露或破坏&#xff0c;会对个人、组织和国家造成严重的损失。 以下是数据安全的重要性&#xff1a; 1. 保护各类隐私&#x…...

要创建富文本内容?Kendo UI Angular组件有专门的编辑器应对!

您的Angular应用程序可能需要允许用户添加带有格式化选项的文本、图像、表格、外观样式和/或链接&#xff0c;使用Kendo UI for Angular的编辑器&#xff0c;可以轻松搞定这些&#xff01; Kendo UI for Angular是专业级的Angular UI组件库&#xff0c;不仅是将其他供应商提供…...

工赋开发者社区 | 装备制造企业数字化转型总体框架

导读 当前&#xff0c;面对技术、市场以及供应链等多重挑战&#xff0c;在软件定义、数据驱动、数字孪生、大数据、人工智能及元宇宙等技术加持下&#xff0c;装备制造企业不断采用新工艺、新材料&#xff0c;以新模式推动产品快速创新。企业积极关注并探索数字化转型路径&…...

Python趋势外推预测模型实验完整版

趋势外推预测模型实验完整版 实验目的 通过趋势外推预测模型&#xff08;佩尔预测模型&#xff09;&#xff0c;掌握预测模型的建立和应用方法&#xff0c;了解趋势外推预测模型&#xff08;佩尔预测模型&#xff09;的基本原理 实验内容 趋势外推预测模型 实验步骤和过程…...

KALI入门到高级【第三章】

预计更新第一章 入门 1.1 什么是Kali Linux&#xff1f; 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 特…...

React Native中防止滑动过程中误触

React Native中防止滑动过程中误触 在使用React Native开发的时&#xff0c;当我们快速滑动应用的时候&#xff0c;可能会出现误触&#xff0c;导致我们会点击到页面中的某一些点击事件&#xff0c;误触导致页面元素响应从而进行其他操作,表现出非常不好的用户体验。 一、问题…...

【c语言】函数递归调用

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ…...

SPSS如何进行判别分析之案例实训?

文章目录 0.引言1.一般判别分析2.逐步判别分析3.决策树分析 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对判别分析进行阐述。 1…...

Windows 10 字体模糊发虚的问题及解决方法

Windows 10字体模糊发虚! 如何解决?Windows 10是一款常见的操作系统&#xff0c;它拥有各种各样的功能&#xff0c;但是有些用户发现&#xff0c;在使用Windows 10时&#xff0c;字体会变得模糊发虚&#xff0c;这给用户带来了很多不便。下面&#xff0c;我们就来看看如何解决…...

渔人杯部分wp

文章目录 渔人杯神仙姐姐阿拉丁飘啊飘 渔人杯 神仙姐姐 点击拜 &#xff0c;抓包发现get请求了/sx.php 返回如下 {"code":0,"num":1,"flag":"ctfsh0w-f1ag-n0t-h3r3-th1s-msg-just-a-j0ke-}{"}在repeater重复请求&#xff0c;发现…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...