java后端生成心电图-jfreechart

article/2025/6/7 22:51:57

用jfreechart生成心电图

先上成功的图片

在这里插入图片描述

上代码

1.导入包

  implementation 'org.jfree:jfreechart:1.5.4'implementation 'org.jfree:jcommon:1.0.24'

2.实现代码

对数据进行滤波
转换单位
package com.shinrun.infrastructure.util;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class ECGDataConverter {/*** 将原始数据转换为mV单位的数据* @param rawData 原始数据数组* @param scaleFactor 比例因子(20000对应1mV)* @return 转换后的数据数组(单位mV)*/public static double[] convertToMillivolts(double[] rawData, double scaleFactor) {double[] convertedData = new double[rawData.length];for (int i = 0; i < rawData.length; i++) {convertedData[i] = rawData[i] / scaleFactor;}return convertedData;}/*** 将原始数据转换为微伏(uV)单位的数据* @param rawData 原始数据数组* @param scaleFactor 比例因子(20000对应1mV)* @return 转换后的数据数组(单位uV)*/public static double[] convertToMicrovolts(double[] rawData, double scaleFactor) {double[] convertedData = new double[rawData.length];for (int i = 0; i < rawData.length; i++) {convertedData[i] = (rawData[i] / scaleFactor) * 1000; // 转换为uV}return convertedData;}/*** 移动平均滤波器 - 平滑高频噪声* @param data 原始ECG数据(uV)* @param windowSize 窗口大小(建议3-7)* @return 滤波后的数据*/public static double[] movingAverageFilter(double[] data, int windowSize) {if (windowSize < 1 || windowSize > data.length) {throw new IllegalArgumentException("Invalid window size");}double[] filtered = new double[data.length];int halfWindow = windowSize / 2;for (int i = 0; i < data.length; i++) {int start = Math.max(0, i - halfWindow);int end = Math.min(data.length - 1, i + halfWindow);double sum = 0;int count = 0;for (int j = start; j <= end; j++) {sum += data[j];count++;}filtered[i] = sum / count;}return filtered;}/*** 中值滤波器 - 有效去除脉冲噪声* @param data 原始ECG数据(uV)* @param windowSize 窗口大小(建议3-5)* @return 滤波后的数据*/public static double[] medianFilter(double[] data, int windowSize) {if (windowSize < 1 || windowSize > data.length || windowSize % 2 == 0) {throw new IllegalArgumentException("Window size must be odd and positive");}double[] filtered = new double[data.length];int halfWindow = windowSize / 2;double[] window = new double[windowSize];for (int i = 0; i < data.length; i++) {int start = Math.max(0, i - halfWindow);int end = Math.min(data.length - 1, i + halfWindow);// 填充窗口int index = 0;for (int j = start; j <= end; j++) {window[index++] = data[j];}// 对窗口数据进行排序Arrays.sort(window, 0, index);// 取中值filtered[i] = window[index / 2];}return filtered;}/*** 基于阈值的异常值过滤* @param data 原始ECG数据(uV)* @param thresholdMultiplier 阈值乘数(建议2.5-3.5)* @return 过滤后的数据*/public static double[] thresholdFilter(double[] data, double thresholdMultiplier) {// 计算数据的均值和标准差double mean = 0;for (double v : data) {mean += v;}mean /= data.length;double stdDev = 0;for (double v : data) {stdDev += Math.pow(v - mean, 2);}stdDev = Math.sqrt(stdDev / data.length);double threshold = thresholdMultiplier * stdDev;double[] filtered = new double[data.length];for (int i = 0; i < data.length; i++) {if (Math.abs(data[i] - mean) > threshold) {// 如果是异常值,用前后值的平均值替代double prev = i > 0 ? filtered[i-1] : mean;double next = i < data.length-1 ? data[i+1] : mean;filtered[i] = (prev + next) / 2;} else {filtered[i] = data[i];}}return filtered;}/*** 组合滤波器 - 先中值滤波再移动平均* @param data 原始ECG数据(uV)* @param medianWindow 中值滤波窗口大小(建议3)* @param averageWindow 移动平均窗口大小(建议5)* @return 滤波后的数据*/public static double[] combinedFilter(double[] data, int medianWindow, int averageWindow) {double[] medianFiltered = medianFilter(data, medianWindow);return movingAverageFilter(medianFiltered, averageWindow);}/*** 原始数据强过滤(处理ADC值)* @param rawData 原始ADC数据* @param maxAllowed 允许的最大ADC绝对值* @return 过滤后的原始ADC数据*/public static double[] filterRawData(double[] rawData, double maxAllowed) {if (rawData == null) {return new double[0];}double[] filtered = Arrays.copyOf(rawData, rawData.length);int windowSize = 7; // 使用前后各3个点(共7点窗口)for (int i = 0; i < filtered.length; i++) {if (Math.abs(filtered[i]) > maxAllowed) {// 获取周围正常值的滑动窗口中值filtered[i] = getSlidingWindowReplacement(filtered, i, windowSize, maxAllowed);}}return filtered;}private static double getSlidingWindowReplacement(double[] data, int centerIdx,int windowSize, double maxAllowed) {int halfWindow = windowSize / 2;List<Double> validValues = new ArrayList<>();// 收集窗口内有效值for (int i = -halfWindow; i <= halfWindow; i++) {int actualIdx = centerIdx + i;if (actualIdx >= 0 && actualIdx < data.length &&Math.abs(data[actualIdx]) <= maxAllowed) {validValues.add(data[actualIdx]);}}// 处理策略(按优先级):if (!validValues.isEmpty()) {// 1. 有有效值则取中位数Collections.sort(validValues);return validValues.get(validValues.size() / 2);} else {// 2. 无有效值则取前一个正常值(向前搜索)for (int i = centerIdx - 1; i >= 0; i--) {if (Math.abs(data[i]) <= maxAllowed) {return data[i];}}// 3. 极端情况返回0return 0.0;}}}
图片生成 方法
package com.shinrun.infrastructure.util;import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.ui.RectangleInsets;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;/*** 医疗级心电图生成工具类(10段垂直排列)* 实现了标准心电图纸网格和比例尺*/
public class ECGChartGenerator {// ============= 默认参数配置 =============private static final int DEFAULT_SAMPLE_RATE = 500; // 默认采样率500Hzprivate static final int SEGMENT_COUNT = 10; // 固定10段心电图private static final int DEFAULT_WIDTH = 800; // 图片默认宽度private static final int SEGMENT_HEIGHT = 150; // 每段心电图高度private static final int TOTAL_HEIGHT = SEGMENT_COUNT * SEGMENT_HEIGHT; // 总高度// 心电图纸网格参数(医疗标准)private static final int SMALL_GRID_MM = 1; // 小方格1mmprivate static final int LARGE_GRID_MM = 5; // 大方格5mm(5个小方格)private static final int GRID_SIZE_PX = 12; // 1mm对应的像素数(方法二)// 心电图显示参数private static final double DEFAULT_MM_PER_MV = 10.0; // 标准灵敏度:10mm/mVprivate static final double DEFAULT_PAPER_SPEED_MM_PER_SEC = 25.0; // 标准走纸速度:25mm/sprivate static final int DEFAULT_HEIGHT = 600; // 图片默认高度/*** 生成无标签的心电图纸网格*/public static String generateECGGrid() throws IOException {// 创建空数据集(不需要实际数据)XYSeriesCollection dataset = new XYSeriesCollection();// 创建图表JFreeChart chart = ChartFactory.createXYLineChart(null, "", "", dataset);// 自定义网格样式customizeGridChart(chart);return convertChartToBase64(chart, DEFAULT_WIDTH, DEFAULT_HEIGHT);}/*** 自定义网格图表样式*/private static void customizeGridChart(JFreeChart chart) {XYPlot plot = chart.getXYPlot();// 1. 背景设置plot.setBackgroundPaint(Color.WHITE);chart.setBackgroundPaint(Color.WHITE);// 2. 网格线设置(医疗标准)plot.setDomainGridlinePaint(new Color(255, 200, 200)); // 小网格线颜色plot.setRangeGridlinePaint(new Color(255, 200, 200));plot.setDomainGridlineStroke(new BasicStroke(0.5f));   // 小网格线宽度plot.setRangeGridlineStroke(new BasicStroke(0.5f));// 计算网格大小(像素)double smallGridPx = SMALL_GRID_MM * GRID_SIZE_PX;double largeGridPx = LARGE_GRID_MM * GRID_SIZE_PX;// 3. X轴(时间轴)设置 - 隐藏所有标签和刻度NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();xAxis.setAxisLineVisible(false);xAxis.setTickMarksVisible(false);xAxis.setTickLabelsVisible(false);xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());xAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));// 4. Y轴(幅度轴)设置 - 隐藏所有标签和刻度NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();yAxis.setAxisLineVisible(false);yAxis.setTickMarksVisible(false);yAxis.setTickLabelsVisible(false);yAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));// 5. 移除所有渲染器(因为我们只需要网格)plot.setRenderer(null);// 6. 调整图表边距plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5));// 7. 确保没有图例chart.removeLegend();// 8. 设置合适的范围以显示网格xAxis.setRange(0, DEFAULT_WIDTH / GRID_SIZE_PX);yAxis.setRange(0, DEFAULT_HEIGHT / GRID_SIZE_PX);}/*** 使用默认参数生成10段ECG Base64图片*/public static String generateSegmentedECGImage(double[] ecgData) throws IOException {return generateSegmentedECGImage(ecgData, DEFAULT_SAMPLE_RATE, DEFAULT_MM_PER_MV, DEFAULT_PAPER_SPEED_MM_PER_SEC);}/*** 自定义参数生成10段ECG Base64图片*/public static String generateSegmentedECGImage(double[] ecgData, int sampleRate, double mmPerMv, double paperSpeedMmPerSec) throws IOException {// 计算每段数据点数int pointsPerSegment = ecgData.length / SEGMENT_COUNT;XYSeriesCollection dataset = new XYSeriesCollection();// 创建10个数据段for (int seg = 0; seg < SEGMENT_COUNT; seg++) {int start = seg * pointsPerSegment;int end = (seg == SEGMENT_COUNT - 1) ? ecgData.length : start + pointsPerSegment;XYSeries series = new XYSeries("ECG Segment " + (seg + 1));// 垂直偏移量(使各段分开显示)double yOffset = -seg * 2.0; // 每段下移2mVfor (int i = start; i < end; i++) {// 计算时间并转换为毫米(基于走纸速度)double timeSec = (i - start) / (double) sampleRate;double xPosMm = timeSec * paperSpeedMmPerSec;// 转换为像素double xPixel = xPosMm * GRID_SIZE_PX;// 转换ECG值到mV(输入是uV)double valueMv = ecgData[i] / 1000.0;// 应用垂直比例尺(mm/mV)double yPosMm = valueMv * mmPerMv;// 转换为像素并加上偏移量double yPixel = yPosMm * GRID_SIZE_PX + (yOffset * mmPerMv * GRID_SIZE_PX);series.add(xPixel, yPixel);}dataset.addSeries(series);}// 创建图表JFreeChart chart = ChartFactory.createXYLineChart(null, "时间 (mm)", "幅度 (mm)", dataset);// 自定义心电图样式customizeMedicalECGChart(chart, mmPerMv, paperSpeedMmPerSec);return convertChartToBase64(chart, DEFAULT_WIDTH, TOTAL_HEIGHT);}/*** 自定义心电图图表样式(医疗标准)*/private static void customizeMedicalECGChart(JFreeChart chart, double mmPerMv, double paperSpeedMmPerSec) {XYPlot plot = chart.getXYPlot();// 1. 背景设置plot.setBackgroundPaint(Color.WHITE);chart.setBackgroundPaint(Color.WHITE);// 2. 网格线设置(医疗标准)plot.setDomainGridlinePaint(new Color(255, 200, 200)); // 小网格线颜色plot.setRangeGridlinePaint(new Color(255, 200, 200));plot.setDomainGridlineStroke(new BasicStroke(0.5f));   // 小网格线宽度plot.setRangeGridlineStroke(new BasicStroke(0.5f));// 计算网格大小(像素)double smallGridPx = SMALL_GRID_MM * GRID_SIZE_PX;double largeGridPx = LARGE_GRID_MM * GRID_SIZE_PX;// 3. X轴(时间轴)设置NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();xAxis.setAxisLinePaint(Color.BLACK);xAxis.setTickMarkPaint(Color.BLACK);xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());xAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));// 新版JFreeChart不再支持setMinorTickMarkPaint,改用以下方式设置次刻度xAxis.setMinorTickCount(4);xAxis.setMinorTickMarksVisible(true);// 4. Y轴(幅度轴)设置NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();yAxis.setAxisLinePaint(Color.BLACK);yAxis.setTickMarkPaint(Color.BLACK);yAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));yAxis.setMinorTickCount(4);yAxis.setMinorTickMarksVisible(true);// 5. 心电图曲线渲染设置XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();renderer.setSeriesPaint(0, Color.BLACK);renderer.setSeriesStroke(0, new BasicStroke(1.5f));// 为所有段应用相同的渲染器for (int i = 0; i < SEGMENT_COUNT; i++) {plot.setRenderer(i, renderer);renderer.setSeriesPaint(i, Color.BLACK);renderer.setSeriesStroke(i, new BasicStroke(1.5f));renderer.setSeriesShapesVisible(i, false);}// 6. 调整图表边距plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5));// 7. 移除图例chart.removeLegend();// 8. 添加标题显示参数chart.setTitle("心电图 - " + mmPerMv + "mm/mV, 走纸速度 " + paperSpeedMmPerSec + "mm/s");}/*** 使用默认参数生成10段ECG Base64图片(无刻度值)*/public static String generateSegmentedECGImageNoLabels(double[] ecgData) throws IOException {return generateSegmentedECGImageNoLabels(ecgData, DEFAULT_SAMPLE_RATE,DEFAULT_MM_PER_MV, DEFAULT_PAPER_SPEED_MM_PER_SEC);}/*** 自定义参数生成10段ECG Base64图片(无刻度值)*/public static String generateSegmentedECGImageNoLabels(double[] ecgData, int sampleRate,double mmPerMv, double paperSpeedMmPerSec) throws IOException {// 计算每段数据点数int pointsPerSegment = ecgData.length / SEGMENT_COUNT;XYSeriesCollection dataset = new XYSeriesCollection();// 创建10个数据段for (int seg = 0; seg < SEGMENT_COUNT; seg++) {int start = seg * pointsPerSegment;int end = (seg == SEGMENT_COUNT - 1) ? ecgData.length : start + pointsPerSegment;XYSeries series = new XYSeries("ECG Segment " + (seg + 1));// 垂直偏移量(使各段分开显示)double yOffset = -seg * 2.0; // 每段下移2mVfor (int i = start; i < end; i++) {// 计算时间并转换为毫米(基于走纸速度)double timeSec = (i - start) / (double) sampleRate;double xPosMm = timeSec * paperSpeedMmPerSec;// 转换为像素double xPixel = xPosMm * GRID_SIZE_PX;// 转换ECG值到mV(输入是uV)double valueMv = ecgData[i] / 1000.0;// 应用垂直比例尺(mm/mV)double yPosMm = valueMv * mmPerMv;// 转换为像素并加上偏移量double yPixel = yPosMm * GRID_SIZE_PX + (yOffset * mmPerMv * GRID_SIZE_PX);series.add(xPixel, yPixel);}dataset.addSeries(series);}// 创建图表JFreeChart chart = ChartFactory.createXYLineChart(null, "", "", dataset); // 空标题和空轴标签// 自定义心电图样式(无刻度值)customizeMedicalECGChartNoLabels(chart, mmPerMv, paperSpeedMmPerSec);return convertChartToBase64(chart, DEFAULT_WIDTH, TOTAL_HEIGHT);}/*** 自定义心电图图表样式(医疗标准,无刻度值)*/private static void customizeMedicalECGChartNoLabels(JFreeChart chart, double mmPerMv, double paperSpeedMmPerSec) {XYPlot plot = chart.getXYPlot();// 1. 背景设置plot.setBackgroundPaint(Color.WHITE);chart.setBackgroundPaint(Color.WHITE);// 2. 网格线设置(医疗标准)plot.setDomainGridlinePaint(new Color(255, 200, 200)); // 小网格线颜色plot.setRangeGridlinePaint(new Color(255, 200, 200));plot.setDomainGridlineStroke(new BasicStroke(0.5f));   // 小网格线宽度plot.setRangeGridlineStroke(new BasicStroke(0.5f));// 计算网格大小(像素)double smallGridPx = SMALL_GRID_MM * GRID_SIZE_PX;double largeGridPx = LARGE_GRID_MM * GRID_SIZE_PX;// 3. X轴(时间轴)设置 - 隐藏刻度值NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();xAxis.setAxisLineVisible(false);          // 隐藏轴线xAxis.setTickMarksVisible(false);         // 隐藏刻度线xAxis.setTickLabelsVisible(false);        // 隐藏刻度标签xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());xAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));// 4. Y轴(幅度轴)设置 - 隐藏刻度值NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();yAxis.setAxisLineVisible(false);          // 隐藏轴线yAxis.setTickMarksVisible(false);         // 隐藏刻度线yAxis.setTickLabelsVisible(false);        // 隐藏刻度标签yAxis.setTickUnit(new org.jfree.chart.axis.NumberTickUnit(largeGridPx));// 5. 心电图曲线渲染设置XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();renderer.setSeriesPaint(0, Color.BLACK);renderer.setSeriesStroke(0, new BasicStroke(0.8f));// 为所有段应用相同的渲染器for (int i = 0; i < SEGMENT_COUNT; i++) {plot.setRenderer(i, renderer);renderer.setSeriesPaint(i, Color.BLACK);renderer.setSeriesStroke(i, new BasicStroke(0.8f));renderer.setSeriesShapesVisible(i, false);}// 6. 调整图表边距plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5));// 7. 移除图例chart.removeLegend();// 8. 移除标题chart.setTitle("心电图 - " + mmPerMv + "mm/mV, 走纸速度 " + paperSpeedMmPerSec + "mm/s");}/*** 将图表转换为Base64编码的PNG图片*/private static String convertChartToBase64(JFreeChart chart, int width, int height) throws IOException {try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {ChartUtils.writeChartAsPNG(outputStream, chart, width, height);return "data:image/png;base64," + Base64.getEncoder().encodeToString(outputStream.toByteArray());}}
}
讲解使用

我的心电图数据是来着于第三方平台的(是由机器将心电数据文件上传到第三方系统,第三方系统给我返回的double数组)

首先是进行 滤波,数据会有很大的外界因素影响,波动会很大,
再将数据转换成mv
再画图,进行调试

  public String generateEcg(double[] rawData ) {// 转换参数double scaleFactor = 20.0;String oss="";// 方法1: 使用默认参数处理double[] processedECG = ECGDataConverter.filterRawData(rawData,4000);//转换成mvdouble[] doubles = ECGDataConverter.convertToMillivolts(processedECG, scaleFactor);// 生成时间轴try {String string = ECGChartGenerator.generateSegmentedECGImageNoLabels(doubles);oss= uploadFile(string, "image/ecg");} catch (IOException e) {throw new RuntimeException(e);}return oss;}
关键点
double[] processedECG = ECGDataConverter.filterRawData(rawData,4000);

这里 滤波参数我给的4000 其实就是 将超过4000的值给过滤掉,第三方给的数据 人的平均心跳峰值不超过4000,超过4000的那就不对需要过滤掉,这个根据你实际的数据进行修改

    double scaleFactor = 20.0;//转换成mvdouble[] doubles = ECGDataConverter.convertToMillivolts(processedECG, scaleFactor);

这里传个参数scaleFactor ,其实就是对数据进行除一下,这里由于第三方给的数据不太规范,不除以一下的话画出来不太好看
一般数据除到是百位数就行了

如果上面两点没有做好的话效果可能如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.hkcw.cn/article/rJercsYWbe.shtml

相关文章

项目前置知识——不定参以及设计模式

1.C语言不定参宏函数 c语言中&#xff0c;printf就是一个不定参函数&#xff0c;在使用不定参宏函数时&#xff0c;我们使用__VA_ARGS__来解析不定参&#xff1a; #include <iostream> #include <cstdarg>#define LOG(fmt/*格式*/, .../*用...表示不定参*/) prin…

redis哨兵与集群部署

目录 一.哨兵模式部署 1.设置Redis哨兵模式配置文件的属组以及属主&#xff08;所有节点操作&#xff09; 2.修改Redis哨兵模式的配置文件&#xff08;所有节点操作&#xff09; 3.准备server文件启动&#xff0c;先启主再启从&#xff08;所有节点操作&#xff09; 4.验证…

飞腾D2000,麒麟系统V10,docker,ubuntu1804,小白入门喂饭级教程

#下载docker Index of linux/static/stable/ 根据电脑的CPU类型选择&#xff1a; Intel和AMD选x86_64飞腾D2000选aarch64 #选择较新的版本 #在包含下载的docker-XX.X.X.tgz的文件夹中右键->打开终端 # 解压安装包&#xff08;根据实际下载的文件&#xff09; tar -zxvf …

torch.nn中的各种组件

Content 线性层 (Linear Layers)**核心原理&#xff1a;线性变换****关键组件****示例代码****示例1&#xff1a;基础线性层 (nn.Linear)****示例2&#xff1a;双线性层 (nn.Bilinear)** **应用场景** 非线性激活函数 (Non-linear Activations)**常用非线性激活函数****1. ReLU…

高性能分布式消息队列系统(二)

上一篇博客将C进行实现消息队列的用到的核心技术以及环境配置进行了详细的说明&#xff0c;这一篇博客进行记录消息队列进行实现的核心模块的设计 五、项目的需求分析 5.1、项目框架的概念性理解 5.1.1、消息队列的设计和生产消费者模型的关系 在现代系统架构中&#xff0c;…

AI健康小屋+微高压氧舱:科技如何重构我们的健康防线?

目前&#xff0c;随着科技和社会的不断发展&#xff0c;人们的生活水平和方式有了翻天覆地的变化。 从吃饱穿暖到吃好喝好再到健康生活&#xff0c;观念也在逐渐发生改变。 尤其是在21世纪&#xff0c;大家对健康越来越重视&#xff0c;这就不得不提AI健康小屋和氧舱。 一、A…

Azure DevOps Server 2022.2 补丁(Patch 5)

微软Azure DevOps Server的产品组在4月8日发布了2022.2 的第5个补丁。下载路径为&#xff1a;https://aka.ms/devops2022.2patch5 这个补丁的主要功能是修改了代理(Agent)二进制安装文件的下载路径&#xff1b;之前&#xff0c;微软使用这个CND(域名为vstsagentpackage.azuree…

Rag技术----项目博客(六)

RAG 定义&#xff1a;检索增强生成&#xff08;Retrieval Augmented Generation&#xff09;&#xff0c;简称 RAG&#xff0c;已经成为当前最火热的LLM应用方案。 目的&#xff1a;通过提供相关领域数据库通过问题检索信息&#xff0c;将相关信息合并到Prompt中&#xff0c;…

BioID技术:揭示铁死亡机制中Caspase-2蛋白相互作用网络

铁死亡&#xff08;Ferroptosis&#xff09;是一种铁依赖的非凋亡形式的细胞死亡&#xff0c;其发生与细胞内氧化应激失衡以及抗氧化防御途径受损密切相关。随着研究的深入&#xff0c;学界逐渐认识到蛋白质相互作用在铁死亡调控中扮演着关键角色。铁死亡作为一种新型的细胞死亡…

机器学习——随机森林算法

随机森林算法是一种强大的树集成算法&#xff0c;比使用单个决策树效果要好得多。 以下是生成树集成的方法&#xff1a;假设有一个大小为m的训练集&#xff0c;然后对于b1到B&#xff0c;所以执行B次&#xff0c;可以使用有放回抽样来创建一个大小为m的训练集。所以如果有10个…

快速排序(Quick Sort)算法详解(递归与非递归)

引言 在计算机科学中&#xff0c;排序算法是最基础且重要的算法之一。快速排序&#xff08;Quick Sort&#xff09;作为一种高效的排序算法&#xff0c;在实际应用中被广泛使用。平均时间复杂度为 (O(n log n))&#xff0c;最坏情况下为 (O(n^2))。本文将详细介绍快速排序算法…

8.RV1126-OPENCV 视频中添加LOGO

一.视频中添加 LOGO 图像大体流程 首先初始化VI,VENC模块并使能&#xff0c;然后创建两个线程&#xff1a;1.把LOGO灰度化&#xff0c;然后获取VI原始数据&#xff0c;其次把VI数据Mat化并创建一个感兴趣区域&#xff0c;最后把LOGO放感兴趣区域里并把数据发送给VENC。2.专门获…

Linux 下 ChromeDriver 安装

个人博客地址&#xff1a;Linux 下 ChromeDriver 安装 | 一张假钞的真实世界 Selenium 是一个用于 Web 应用程序测试的工具。可以通过它驱动浏览器执行特定的操作&#xff0c;如点击、下滑、资源加载与渲染等。该工具在爬虫开发中也非常有帮助。Selenium 需要通过浏览器驱动操…

C++学者给您讲数学之——数列

C学者为您解析数列基础 数列的概念 **数列&#xff08;sequence of number&#xff09;**是以正整数集&#xff08;或其有限子集&#xff09;为定义域的有序数集。数列中的每个数称为该数列的项&#xff0c;其中&#xff1a; 第一位称为第1项&#xff08;首项&#xff09; 第…

【Harmony OS】数据存储

目录 数据存储概述 首选项数据存储 关系型数据库 数据存储概述 • 数据存储 是为了解决应用数据持久化问题&#xff0c;使得数据能够存储在外存中&#xff0c;达到保存或共享目的。 • 鸿蒙应用数据存储包括 本地数据存储 和 分布式数据存储 。 • 本地数据存储 为应用…

程序员健康防护指南

深度学习欢迎访问&#xff1a;通义灵码2.5qwen3——节假日抢票不用愁&#xff0c;基于12306-MCP实现个人火车票智能查询小助手&#xff01;-CSDN博客 一、视觉系统防护工程 1. 数字眼疲劳综合征防控 蓝光管理&#xff1a;使用经认证的防蓝光眼镜可过滤45%有害蓝光&#xff0c;…

CSS 平铺+自动换行效果

先上效果图 样式 <template><div class"activity-questions"><h1>活动题库</h1><div v-if"loading" class"loading">加载中...</div><div v-else><div v-if"questions.length 0" clas…

苏超火了 “苏大强”的作业怎么抄 全网热潮背后的足球盛宴

“比赛第一,友谊第十四”是这里的原则。近日,江苏省首届城市足球联赛“苏超”火出圈。“苏超”由江苏省体育局与江苏省各设区市政府联合主办,13个设区市各派一队参加。联赛打破了准入的边界,队伍中既有职业球员也有个体工商户、大学生和高中生等业余球员。尽管球员水平与中…

ck-editor5的研究 (7):自定义配置 CKeditor5 的 toolbar 工具栏

文章目录 一、前言二、实现步骤1. 第一步: 搭建目录结构2. 第二步:配置toolbar工具栏的步骤(2-1). 配置粗体和斜体(2-2). 配置链接和标题+正文(2-3). 配置列表和引用(2-4). 配置自动格式化3. 第三步:更多工具三、测试效果和细节四、总结一、前言 在前面的文章中,我们已经对…

Skydel25.4发布:解锁自定义星座,增强C波段与干扰模拟能力

在GNSS模拟技术持续迭代的浪潮中&#xff0c;Skydel迈出创新一步&#xff0c;正式发布25.4.0版本及后续修复版本25.4.1。本次更新的核心突破在于引入了强大的自定义星座功能&#xff0c;赋予用户前所未有的自由度&#xff0c;可创建包含多达400颗卫星的专属星座&#xff0c;突破…