学习yolo+Java+opencv简单案例(三)

主要内容:车牌检测+识别(什么颜色的车牌,车牌号)

模型作用:车牌检测,车牌识别

文章的最后附上我的源码地址。

学习还可以参考我前两篇博客:

学习yolo+Java+opencv简单案例(一)-CSDN博客

学习yolo+Java+opencv简单案例(二)-CSDN博客

目录

一、模型示例

二、解释流程

1、加载opencv库

2、定义车牌颜色和字符

3、模型路径和图片路径

4、创建目录

5、加载onnx模型

6、车牌检测和识别

7、辅助方法

三、代码实现

1、pom.xml

2、controller

四、测试


一、模型示例

二、解释流程

1、加载opencv库
static {// 加载opencv动态库,nu.pattern.OpenCV.loadLocally();
}
2、定义车牌颜色和字符
final static String[] PLATE_COLOR = new String[]{"黑牌", "蓝牌", "绿牌", "白牌", "黄牌"};
final static String PLATE_NAME= "#京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民航危0123456789ABCDEFGHJKLMNPQRSTUVWXYZ险品";
3、模型路径和图片路径
// 车牌检测模型
String model_path1 = "./PlateDetection/src/main/resources/model/plate_detect.onnx";// 车牌识别模型
String model_path2 = "./PlateDetection/src/main/resources/model/plate_rec_color.onnx";// 要检测的图片所在目录
String imagePath = "./yolo-common/src/main/java/com/bluefoxyu/carImg";// 定义保存目录
String outputDir = "./PlateDetection/output/";
4、创建目录
File directory = new File(outputDir);
if (!directory.exists()) {directory.mkdirs();  // 创建目录System.out.println("目录不存在,已创建:" + outputDir);
}

5、加载onnx模型
// 加载ONNX模型
OrtEnvironment environment = OrtEnvironment.getEnvironment();
OrtSession.SessionOptions sessionOptions = new OrtSession.SessionOptions();
OrtSession session = environment.createSession(model_path1, sessionOptions);// 加载ONNX模型
OrtEnvironment environment2 = OrtEnvironment.getEnvironment();
OrtSession session2 = environment2.createSession(model_path2, sessionOptions);

使用 ONNX Runtime 加载两个模型,一个用于车牌检测,另一个用于车牌识别。

6、车牌检测和识别

(1)处理每一张图片:

Map<String, String> map = getImagePathMap(imagePath);
for(String fileName : map.keySet()){// 处理图片逻辑
}

(2)读取和预处理图片:

Mat img = Imgcodecs.imread(imageFilePath);
Mat image = img.clone();
Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGB);

使用 OpenCV 读取图片并进行颜色空间转换(从 BGR 转换为 RGB)。

(3)图像尺寸调整

Letterbox letterbox = new Letterbox();
image = letterbox.letterbox(image);

使用 Letterbox 方法调整图像的尺寸,使其适应模型的输入要求。

(4)模型推理(车牌检测)

float[] chw = ImageUtil.whc2cwh(whc);
OnnxTensor tensor = OnnxTensor.createTensor(environment, FloatBuffer.wrap(chw),shape );
OrtSession.Result output = session.run(stringOnnxTensorHashMap);

将预处理后的图像转换为 ONNX Tensor 格式,并使用车牌检测模型进行推理。

(5)非极大值抑制

List<float[]> bboxes = nonMaxSuppression(bboxes, nmsThreshold);

使用非极大值抑制(NMS)来过滤重叠的检测框,只保留最有可能的车牌位置。

(6)车牌裁剪和识别

Mat image2 = new Mat(img.clone(), rect);
// 车牌识别模型推理
OrtSession.Result output2 = session2.run(stringOnnxTensorHashMap2);
String plateNo = decodePlate(maxScoreIndex(result[0]));

使用检测到的车牌位置,裁剪出车牌区域,再使用车牌识别模型进行识别,得到车牌号码和颜色。

(7)结果展示和保存

BufferedImage bufferedImage = matToBufferedImage(img);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawString(PLATE_COLOR[colorRResult[0].intValue()]+"-"+plateNo, (int)((bbox[0]-dw)/ratio), (int)((bbox[1]-dh)/ratio-3));
ImageIO.write(bufferedImage, "jpg", new File(outputPath));
7、辅助方法

xywh2xyxy: 将中心点坐标转换为边框坐标。

nonMaxSuppression: 实现非极大值抑制。

matToBufferedImage: 将 OpenCV 的 Mat 对象转换为 Java 的 BufferedImage,以便进行图像处理。

argmax: 找出最大值的索引,用于推理时的结果处理。

softMax: 实现 softmax 函数,用于将输出转化为概率分布。

decodePlatedecodeColor: 用于解码模型输出的车牌字符和颜色。

三、代码实现

1、pom.xml
yolo-study:
<?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>com.bluefoxyu</groupId><artifactId>yolo-study</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>predict-test</module><module>CameraDetection</module><module>yolo-common</module><module>CameraDetectionWarn</module><module>PlateDetection</module><module>dp</module></modules><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.microsoft.onnxruntime</groupId><artifactId>onnxruntime</artifactId><version>1.16.1</version></dependency><dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.7.0-0</version></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version><scope>provided</scope></dependency></dependencies></project>
PlateDetection:
<?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><parent><groupId>com.bluefoxyu</groupId><artifactId>yolo-study</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>PlateDetection</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.bluefoxyu</groupId><artifactId>yolo-common</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.2.4</version></dependency></dependencies></project>
2、controller
@RestController
@RequestMapping("/plate-detect")
public class PlateDetectionController {static {// 加载opencv动态库,//System.load(ClassLoader.getSystemResource("lib/opencv_videoio_ffmpeg470_64.dll").getPath());nu.pattern.OpenCV.loadLocally();}final static String[] PLATE_COLOR = new String[]{"黑牌", "蓝牌", "绿牌", "白牌", "黄牌"};final static String PLATE_NAME= "#京沪津渝冀晋蒙辽" +"吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民航危0123456789ABCDEFGHJKLMNPQRSTUVWXYZ险品";@PostMappingpublic List<String> plateDetection() throws OrtException {//记录车牌号返回前端List<String>plateNumberList=new ArrayList<>();// 车牌检测模型String model_path1 = "./PlateDetection/src/main/resources/model/plate_detect.onnx";// 车牌识别模型String model_path2 = "./PlateDetection/src/main/resources/model/plate_rec_color.onnx";// 要检测的图片所在目录String imagePath = "./yolo-common/src/main/java/com/bluefoxyu/carImg";// 定义保存目录String outputDir = "./PlateDetection/output/";// 用于区别后续各个图片的标识int index=0;// 创建目录(如果不存在)File directory = new File(outputDir);if (!directory.exists()) {directory.mkdirs();  // 创建目录System.out.println("目录不存在,已创建:" + outputDir);}float confThreshold = 0.35F;float nmsThreshold = 0.45F;// 1.单行蓝牌// 2.单行黄牌// 3.新能源车牌// 4.白色警用车牌// 5.教练车牌// 6.武警车牌// 7.双层黄牌// 8.双层白牌// 9.使馆车牌// 10.港澳粤Z牌// 11.双层绿牌// 12.民航车牌String[] labels = {"1", "2", "3", "4", "5", "6", "7","8", "9", "10", "11","12"};// 加载ONNX模型OrtEnvironment environment = OrtEnvironment.getEnvironment();OrtSession.SessionOptions sessionOptions = new OrtSession.SessionOptions();OrtSession session = environment.createSession(model_path1, sessionOptions);// 加载ONNX模型OrtEnvironment environment2 = OrtEnvironment.getEnvironment();OrtSession session2 = environment2.createSession(model_path2, sessionOptions);// 加载标签及颜色ODConfig odConfig = new ODConfig();Map<String, String> map = getImagePathMap(imagePath);for(String fileName : map.keySet()){// 生成输出文件名index++;String outputFileName = "temp_output_image" + "_" + index + ".jpg";String outputPath = outputDir + outputFileName;System.out.println("outputPath = " + outputPath);String imageFilePath = map.get(fileName);System.out.println(imageFilePath);// 读取 imageMat img = Imgcodecs.imread(imageFilePath);Mat image = img.clone();Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGB);// 在这里先定义下框的粗细、字的大小、字的类型、字的颜色(按比例设置大小粗细比较好一些)int minDwDh = Math.min(img.width(), img.height());int thickness = minDwDh/ODConfig.lineThicknessRatio;long start_time = System.currentTimeMillis();// 更改 image 尺寸Letterbox letterbox = new Letterbox();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();image.convertTo(image, CvType.CV_32FC1, 1. / 255);float[] whc = new float[3 * 640 * 640];image.get(0, 0, whc);float[] chw = ImageUtil.whc2cwh(whc);// 创建OnnxTensor对象long[] shape = { 1L, (long)channels, (long)rows, (long)cols };OnnxTensor tensor = OnnxTensor.createTensor(environment, FloatBuffer.wrap(chw),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];Map<Integer, List<float[]>> class2Bbox = new HashMap<>();for (float[] bbox : outputData) {float score = bbox[4];if (score < confThreshold) continue;float[] conditionalProbabilities = Arrays.copyOfRange(bbox, 5, bbox.length);int label = argmax(conditionalProbabilities);// xywh to (x1, y1, x2, y2)xywh2xyxy(bbox);// 去除无效结果if (bbox[0] >= bbox[2] || bbox[1] >= bbox[3]) continue;class2Bbox.putIfAbsent(label, new ArrayList<>());class2Bbox.get(label).add(bbox);}List<CarDetection> CarDetections = new ArrayList<>();for (Map.Entry<Integer, List<float[]>> entry : class2Bbox.entrySet()) {List<float[]> bboxes = entry.getValue();bboxes = nonMaxSuppression(bboxes, nmsThreshold);for (float[] bbox : bboxes) {String labelString = labels[entry.getKey()];CarDetections.add(new CarDetection(labelString,entry.getKey(), Arrays.copyOfRange(bbox, 0, 4), bbox[4],bbox[13] == 0,0.0f,null,null));}}for (CarDetection carDetection : CarDetections) {float[] bbox = carDetection.getBbox();Rect rect = new Rect(new Point((bbox[0]-dw)/ratio, (bbox[1]-dh)/ratio), new Point((bbox[2]-dw)/ratio, (bbox[3]-dh)/ratio));// img.submat(rect)Mat image2 = new Mat(img.clone(), rect);Imgproc.cvtColor(image2, image2, Imgproc.COLOR_BGR2RGB);Letterbox letterbox2 = new Letterbox(168,48);image2 = letterbox2.letterbox(image2);double ratio2  = letterbox2.getRatio();double dw2 = letterbox2.getDw();double dh2 = letterbox2.getDh();int rows2  = letterbox2.getHeight();int cols2  = letterbox2.getWidth();int channels2 = image2.channels();image2.convertTo(image2, CvType.CV_32FC1, 1. / 255);float[] whc2 = new float[3 * 168 * 48];image2.get(0, 0, whc2);float[] chw2 = ImageUtil.whc2cwh(whc2);// 创建OnnxTensor对象long[] shape2 = { 1L, (long)channels2, (long)rows2, (long)cols2 };OnnxTensor tensor2 = OnnxTensor.createTensor(environment2, FloatBuffer.wrap(chw2), shape2);HashMap<String, OnnxTensor> stringOnnxTensorHashMap2 = new HashMap<>();stringOnnxTensorHashMap2.put(session2.getInputInfo().keySet().iterator().next(), tensor2);// 运行推理OrtSession.Result output2 = session2.run(stringOnnxTensorHashMap2);float[][][] result = (float[][][]) output2.get(0).getValue();String plateNo = decodePlate(maxScoreIndex(result[0]));System.err.println("车牌号码:"+plateNo);plateNumberList.add(plateNo);//车牌颜色识别float[][] color = (float[][]) output2.get(1).getValue();double[] colorSoftMax = softMax(floatToDouble(color[0]));Double[] colorRResult = decodeColor(colorSoftMax);carDetection.setPlateNo(plateNo);carDetection.setPlateColor( PLATE_COLOR[colorRResult[0].intValue()]);Point topLeft = new Point((bbox[0]-dw)/ratio, (bbox[1]-dh)/ratio);Point bottomRight = new Point((bbox[2]-dw)/ratio, (bbox[3]-dh)/ratio);Imgproc.rectangle(img, topLeft, bottomRight, new Scalar(0,255,0), thickness);// 框上写文字BufferedImage bufferedImage = matToBufferedImage(img);Point boxNameLoc = new Point((bbox[0]-dw)/ratio, (bbox[1]-dh)/ratio-3);Graphics2D g2d = bufferedImage.createGraphics();g2d.setFont(new Font("微软雅黑", Font.PLAIN, 20));g2d.setColor(Color.RED);g2d.drawString(PLATE_COLOR[colorRResult[0].intValue()]+"-"+plateNo, (int)((bbox[0]-dw)/ratio), (int)((bbox[1]-dh)/ratio-3)); // 假设的文本位置g2d.dispose();try {ImageIO.write(bufferedImage, "jpg", new File(outputPath));} catch (IOException e) {throw new RuntimeException(e);}}System.out.printf("time:%d ms.", (System.currentTimeMillis() - start_time));System.out.println();// 弹窗展示图像HighGui.imshow("Display Image", Imgcodecs.imread(outputPath));// 按任意按键关闭弹窗画面,结束程序HighGui.waitKey();}HighGui.destroyAllWindows();//System.exit(0);System.out.println("识别完成,车牌信息:"+plateNumberList);return plateNumberList;}public static void xywh2xyxy(float[] bbox) {float x = bbox[0];float y = bbox[1];float w = bbox[2];float h = bbox[3];bbox[0] = x - w * 0.5f;bbox[1] = y - h * 0.5f;bbox[2] = x + w * 0.5f;bbox[3] = y + h * 0.5f;}public static List<float[]> nonMaxSuppression(List<float[]> bboxes, float iouThreshold) {List<float[]> bestBboxes = new ArrayList<>();bboxes.sort(Comparator.comparing(a -> a[4]));while (!bboxes.isEmpty()) {float[] bestBbox = bboxes.remove(bboxes.size() - 1);bestBboxes.add(bestBbox);bboxes = bboxes.stream().filter(a -> computeIOU(a, bestBbox) < iouThreshold).collect(Collectors.toList());}return bestBboxes;}// 单纯为了显示中文演示使用,实际项目中用不到这个public static BufferedImage matToBufferedImage(Mat mat) {int type = BufferedImage.TYPE_BYTE_GRAY;if (mat.channels() > 1) {type = BufferedImage.TYPE_3BYTE_BGR;}int bufferSize = mat.channels() * mat.cols() * mat.rows();byte[] b = new byte[bufferSize];mat.get(0, 0, b); // 获取所有像素数据BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();System.arraycopy(b, 0, targetPixels, 0, b.length);return image;}private static int[] maxScoreIndex(float[][] result){int[] indexes = new int[result.length];for (int i = 0; i < result.length; i++){int index = 0;float max = Float.MIN_VALUE;for (int j = 0; j < result[i].length; j++) {if (max < result[i][j]){max = result[i][j];index = j;}}indexes[i] = index;}return indexes;}public static float computeIOU(float[] box1, float[] box2) {float area1 = (box1[2] - box1[0]) * (box1[3] - box1[1]);float area2 = (box2[2] - box2[0]) * (box2[3] - box2[1]);float left = Math.max(box1[0], box2[0]);float top = Math.max(box1[1], box2[1]);float right = Math.min(box1[2], box2[2]);float bottom = Math.min(box1[3], box2[3]);float interArea = Math.max(right - left, 0) * Math.max(bottom - top, 0);float unionArea = area1 + area2 - interArea;return Math.max(interArea / unionArea, 1e-8f);}private static Double[] decodeColor(double[] indexes){double index = -1;double max = Double.MIN_VALUE;for (int i = 0; i < indexes.length; i++) {if (max < indexes[i]){max = indexes[i];index = i;}}return new Double[]{index, max};}public static double [] floatToDouble(float[] input){if (input == null){return null;}double[] output = new double[input.length];for (int i = 0; i < input.length; i++){output[i] = input[i];}return output;}private static String decodePlate(int[] indexes){int pre = 0;StringBuffer sb = new StringBuffer();for(int index : indexes){if(index != 0 && pre != index){sb.append(PLATE_NAME.charAt(index));}pre = index;}return sb.toString();}//返回最大值的索引public static int argmax(float[] a) {float re = -Float.MAX_VALUE;int arg = -1;for (int i = 0; i < a.length; i++) {if (a[i] >= re) {re = a[i];arg = i;}}return arg;}public static double[] softMax(double[] tensor){if(Arrays.stream(tensor).max().isPresent()){double maxValue = Arrays.stream(tensor).max().getAsDouble();double[] value = Arrays.stream(tensor).map(y-> Math.exp(y - maxValue)).toArray();double total = Arrays.stream(value).sum();return Arrays.stream(value).map(p -> p/total).toArray();}else{throw new NoSuchElementException("No value present");}}public static Map<String, String> getImagePathMap(String imagePath){Map<String, String> map = new TreeMap<>();File file = new File(imagePath);if(file.isFile()){map.put(file.getName(), file.getAbsolutePath());}else if(file.isDirectory()){for(File tmpFile : Objects.requireNonNull(file.listFiles())){map.putAll(getImagePathMap(tmpFile.getPath()));}}return map;}}

剩余一些工具类代码可以看文章最后GitHub地址

四、测试

键盘按任意键继续

最后处理后输出的图片:

最后拿到结果:

识别完成~~

GitHub地址:GitHub - bluefoxyu/yolo-study: 学习yolo+java案例第一次提交

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/408667.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Datawhale X 李宏毅苹果书 AI夏令营-深度学习入门班-task2

一开始假设的模型是ybw1&#xff0c;但在可视化预测值和真实值后&#xff0c;发现数据具有规律性&#xff0c;因此换成7天 额&#xff0c;不知道为什么要在这里这样引入sigmoid函数&#xff0c;有点怪怪的&#xff0c;但确实用无限多的分段函数就能拟合很多曲线 所以这里的意…

5步实现猫眼电影爬虫与k-means算法可视化分析

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

框架——特殊符号处理,模糊查询

1.特殊符号处理 在 mybatis 中的 xml 文件中&#xff0c;存在一些特殊的符号&#xff0c;比如&#xff1a;<、>、"、&、<>等&#xff0c;正常书写mybatis 会报错&#xff0c;需要对这些符号进行转义。具体转义如下所示&#xff1a; 特殊字符 转义字符 &…

【GNSS射频前端】MA2769初识

MAX2769 芯片概述&#xff1a; MAX2769是一款单芯片多系统GNSS接收器&#xff0c;采用Maxim的低功耗SiGe BiCMOS工艺技术。集成了包括双输入低噪声放大器&#xff08;LNA&#xff09;、混频器、图像拒绝滤波器、可编程增益放大器&#xff08;PGA&#xff09;、压控振荡器&#…

微信小游戏授权问题

微信小程序获取用户相关信息的接口&#xff0c;如wx.getUserCloudStorage&#xff0c;报错&#xff1a;please go to mp to announce your privacy usage。 需要在微信公众平台设置用户隐私保护。

(论文解读)Domain Adaptation via Prompt Learning

摘要 无监督域适应( UDA )旨在将从带有标签的源域数据中学习到的模型适应到未标注的目标域数据集。现有的UDA方法通过对齐源域和目标域特征空间来学习领域不变特征。这种对齐是通过约束实现的&#xff0c;例如统计差异最小化或对抗学习。 然而&#xff0c;这些约束会导致语义…

AudioNotes -将音频内容转 markdown

文章目录 一、关于 AudioNotes效果展示音视频识别和整理与音视频内容对话 二、使用方法1、安装 Ollama2、拉取模型3、部署服务3.1 Docker部署&#xff08;推荐&#xff09;&#x1f433;3.2 本地部署 &#x1f4e6; 一、关于 AudioNotes AudioNotes 能够快速提取音视频的内容&…

【C# 】使用List<实体类>

1. 使用List<实体类> 要在C#中使用List<EntityTemp>并实现查找数据输出&#xff0c;首先需要定义EntityTemp类&#xff0c;并创建一个List<EntityTemp>类型的列表。然后&#xff0c;你可以使用LINQ或其他方法来查找和输出数据。 假设EntityTemp类具有一个…

Kafka快速入门:Kafka驱动JavaApi的使用

生产者和消费者是Kafka的核心概念之一&#xff0c;它们在客户端被创建和使用&#xff0c;并且包含了许多与Kafka性能和机制相关的配置。虽然Kafka提供的命令行工具能够执行许多基本操作&#xff0c;但它无法实现所有可能的性能优化。相比之下&#xff0c;使用Java API可以充分利…

zigbee笔记、十五、组播通信原理

一、zigbee四种通讯 1、单播&#xff08;略&#xff09; 2、广播&#xff08;略&#xff09; 3、组播&#xff1a;在zigbee网络中&#xff0c;模块可以用分组来标记&#xff0c;发送的模块如果发送的组号和网络里面标记接收模块的组号相对应&#xff0c;那么这些模块就可以拿到…

C#/.NET/.NET Core技术前沿周刊 | 第 1 期(2024年8.12-8.18)

前言 C#/.NET/.NET Core技术前沿周刊&#xff0c;你的每周技术指南针&#xff01;记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿&#xff0c;助力技术成长与视野拓宽。 欢迎投稿&#xff0c;推荐…

innodb_buffer_pool_size在线缩小操作

一、背景 测试数据库内存32G&#xff0c;只有MySQL数据库&#xff0c;但是innodb_buffer_pool_size设置了24G&#xff0c;导致经常出现lack of memory问题、lack of swap问题。 因为使用了MySQL5.7.36版本&#xff0c;利用innodb_buffer_pool_size参数值可在线调整的新特性&…

C++函数调用栈从何而来

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~ 个人主页&#xff1a; rainInSunny | 个人专栏&#xff1a; C那些事儿、 Qt那些事儿 文章目录 写在前面原理综述x86架构函数调用栈分析如何获取rbp寄存器的值总结 写在前面 程序员对函数调用栈是再熟悉不过了&#xff0c;无论是使用IDE…

基于cubemx的STM32的freertos的串口通信

1、任务描述 使用freertos系统实现电脑调试助手和正点原子开发板STM32F103ZET6的串口通信。 2、cubemx设置 3、程序代码 &#xff08;1&#xff09;添加usart1.c #include "usart1.h"#include "usart.h"/**********重定义函数**********/struct __FILE …

阵列信号处理2_阵列信号最优处理常用准则(CSDN_20240825)

目录 最小均方误差&#xff08;Minimum Square Error&#xff0c;MSE&#xff09;准则 最大信噪比&#xff08;Maximum Signal Noise Ratio&#xff0c;MSNR&#xff09;准则 极大似然&#xff08;Maximum Likehood, ML&#xff09;准则 最小方差无损响应&#xff08;Minim…

速通教程:如何使用Coze+剪映,捏一个爆款悟空视频

程哥最近做了一个和黑神话悟空有关的视频&#xff0c;没想到就火了&#xff0c;视频主打一个玉石风格&#xff0c;就是下面这个视频。 视频请移步飞书观看&#xff1a;黑神话悟空玉石版 制作过程不算很复杂&#xff0c;全程只需要用到Coze智能体和剪映这两个工具。 智能体用…

【JVM】亿级流量调优(一)

亿级流量调优 oop模型 前面的klass模型&#xff0c;它是Java类的元信息在JVM中的存在形式。这个oop模型是Java对象在JVM中的存在形式 内存分配策略: 1.空闲列表2.指针碰撞(jvm采用的) 2.1 top指针:执行的是可用内存的起始位置 2.2 采用CAS的方式3.TLAB 线程私有堆4.PLAB 老年…

使用DropZone+SpringBoot实现图片的上传和浏览

经常在项目中需要使用上传文件功能&#xff0c;找了不少前端上传组件&#xff0c;都不是很好用&#xff0c;今天尝试了一下DropZone&#xff0c;发现不错&#xff0c;顺便记录一下使用过程&#xff0c;方便后续查阅。在做开发的时候&#xff0c;经常需要调研一些技术&#xff0…

C# 运算符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C# 有丰富的内置运算符&#xff0c;分为一下六类&#xff1a; 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符 算术运算符 C# 支持的所有算术运算符。假设变量 A 的值为 10&#xff0c;变量 B 的值…

安全面试常见问题任意文件下载

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 1.1 任意文件下…