c#实现halcon的rle编码blob分析
效果展示
实现功能
- connection
- 膨胀
- 腐蚀
- 开运算
- 闭运算
- 特征计算
核心代码
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;namespace view3d
{// 基础对象类,类似于 Halcon 的 HObjectpublic abstract class HObject{public abstract HObjectType Type { get; }public enum HObjectType{Region,XLD,Image}}// 使用 RLE (Run-Length Encoding) 编码的 HRegion 实现public class HRegion : HObject{public override HObjectType Type => HObjectType.Region;// RLE 编码数据结构: 每行存储起始列和结束列的列表private Dictionary<int, List<Interval>> _rleData = new Dictionary<int, List<Interval>>();// 边界框缓存private Rectangle _boundingBox;private bool _boundingBoxValid = false;// 用于表示一行中的连续区间private struct Interval{public int Start;public int End;public Interval(int start, int end){Start = start;End = end;}public int Length => End - Start + 1;}// 构造函数public HRegion() { }// 从位图创建区域public HRegion(Bitmap bitmap, byte threshold = 128){FromBitmap(bitmap, threshold);}// 从位图二值化并创建区域public void FromBitmap(Bitmap bitmap, byte threshold = 128,byte maxThreshold=255){_rleData.Clear();_boundingBoxValid = false;for (int y = 0; y < bitmap.Height; y++){List<Interval> intervals = new List<Interval>();bool inRegion = false;int startX = 0;for (int x = 0; x < bitmap.Width; x++){Color pixel = bitmap.GetPixel(x, y);byte intensity = (byte)((pixel.R + pixel.G + pixel.B) / 3);bool isForeground = intensity >= threshold && intensity<=maxThreshold;if (isForeground && !inRegion){// 进入区域inRegion = true;startX = x;}else if (!isForeground && inRegion){// 离开区域intervals.Add(new Interval(startX, x - 1));inRegion = false;}}// 处理行末尾仍在区域中的情况if (inRegion){intervals.Add(new Interval(startX, bitmap.Width - 1));}if (intervals.Count > 0){_rleData[y] = intervals;}}UpdateBoundingBox();}// 更新边界框private void UpdateBoundingBox(){if (_rleData.Count == 0){_boundingBox = Rectangle.Empty;_boundingBoxValid = true;return;}int minX = int.MaxValue;int maxX = int.MinValue;int minY = _rleData.Keys.Min();int maxY = _rleData.Keys.Max();foreach (var kvp in _rleData){foreach (var interval in kvp.Value){if (interval.Start < minX) minX = interval.Start;if (interval.End > maxX) maxX = interval.End;}}_boundingBox = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);_boundingBoxValid = true;}// 获取边界框public Rectangle BoundingBox{get{if (!_boundingBoxValid) UpdateBoundingBox();return _boundingBox;}}// 计算区域面积public double Area(){double area = 0;foreach (var intervals in _rleData.Values){foreach (var interval in intervals){area += interval.Length;}}return area;}// 计算重心public PointF CenterOfGravity(){if (_rleData.Count == 0) return PointF.Empty;double sumX = 0, sumY = 0;double totalPixels = 0;foreach (var kvp in _rleData){int y = kvp.Key;foreach (var interval in kvp.Value){int length = interval.Length;double centerX = (interval.Start + interval.End) / 2.0;sumX += centerX * length;sumY += y * length;totalPixels += length;}}if (totalPixels == 0) return PointF.Empty;return new PointF((float)(sumX / totalPixels), (float)(sumY / totalPixels));}// 计算圆度public double Circularity(){double area = Area();if (area == 0) return 0;// 计算周长 (简化版,实际需要更精确的计算)double perimeter = 0;foreach (var kvp in _rleData){int y = kvp.Key;foreach (var interval in kvp.Value){// 上边界if (!_rleData.ContainsKey(y - 1) || !HasPixel(y - 1, interval.Start, interval.End))perimeter += interval.Length;// 下边界if (!_rleData.ContainsKey(y + 1) || !HasPixel(y + 1, interval.Start, interval.End))perimeter += interval.Length;// 左边界perimeter += CountLeftEdges(interval.Start, y);// 右边界perimeter += CountRightEdges(interval.End, y);}}return (4 * Math.PI * area) / (perimeter * perimeter);}private bool HasPixel(int y, int startX, int endX){if (!_rleData.TryGetValue(y, out var intervals))return false;foreach (var interval in intervals){if (interval.Start <= endX && interval.End >= startX)return true;}return false;}private int CountLeftEdges(int x, int y){int count = 0;if (!HasPixel(y, x - 1, x - 1)) count++;return count;}private int CountRightEdges(int x, int y){int count = 0;if (!HasPixel(y, x + 1, x + 1)) count++;return count;}// 转换为位图public Bitmap ToBitmap(Bitmap bitmap, Color color ,bool clear=true){if (_rleData.Count == 0) return new Bitmap(1, 1);Rectangle bb = BoundingBox;//Bitmap bitmap = new Bitmap(bb.Width, bb.Height);if (clear){using (Graphics g = Graphics.FromImage(bitmap)){g.Clear(Color.Black);}}foreach (var kvp in _rleData){int y = kvp.Key ;foreach (var interval in kvp.Value){for (int x = interval.Start ; x <= interval.End ; x++){if (x >= 0 && x < bitmap.Width && y >= 0 && y < bitmap.Height){bitmap.SetPixel(x, y,color);}}}}return bitmap;}// 形态学操作 - 膨胀public HRegion Dilation(int radius){HRegion result = new HRegion();foreach (var kvp in _rleData){int y = kvp.Key;foreach (var interval in kvp.Value){for (int dy = -radius; dy <= radius; dy++){int newY = y + dy;int dx = (int)Math.Sqrt(radius * radius - dy * dy);int newStart = interval.Start - dx;int newEnd = interval.End + dx;if (!result._rleData.TryGetValue(newY, out var intervals)){intervals = new List<Interval>();result._rleData[newY] = intervals;}// 合并重叠或相邻的区间bool merged = false;for (int i = 0; i < intervals.Count; i++){if (newEnd + 1 >= intervals[i].Start && newStart - 1 <= intervals[i].End){// 合并区间int start = Math.Min(newStart, intervals[i].Start);int end = Math.Max(newEnd, intervals[i].End);intervals[i] = new Interval(start, end);merged = true;// 检查是否需要与后面的区间合并while (i + 1 < intervals.Count && intervals[i].End + 1 >= intervals[i + 1].Start){intervals[i] = new Interval(intervals[i].Start, Math.Max(intervals[i].End, intervals[i + 1].End));intervals.RemoveAt(i + 1);}break;}}if (!merged){intervals.Add(new Interval(newStart, newEnd));// 保持区间有序intervals.Sort((a, b) => a.Start.CompareTo(b.Start));}}}}result._boundingBoxValid = false;return result;}// 腐蚀操作入口(自动选择最优策略)public HRegion ErosionOptimized(int radius, bool useCircle = true){if (radius <= 0) return new HRegion();if (_rleData.Count == 0) return new HRegion();// 超大半径直接返回空(优化极端情况)Rectangle bb = BoundingBox;if (radius >= Math.Max(bb.Width, bb.Height) * 2)return new HRegion();// 分阶段腐蚀(自动分解大半径)HRegion result = this;int remainingRadius = radius;while (remainingRadius > 0){int currentRadius = Math.Min(5, remainingRadius); // 单次最大半径=5result = useCircle ?ErosionCircleSingleStep(result, currentRadius) :ErosionRectSingleStep(result, currentRadius);remainingRadius -= currentRadius;}return result;}// 单步圆形腐蚀(并行优化)private HRegion ErosionCircleSingleStep(HRegion region, int radius){var result = new ConcurrentDictionary<int, List<Interval>>();var offsets = PrecomputeCircleOffsets(radius); // 预计算圆形偏移量Parallel.ForEach(region._rleData.Keys, y =>{var erodedIntervals = new List<Interval>();foreach (var interval in region._rleData[y]){int currentStart = -1;for (int x = interval.Start; x <= interval.End; x++){bool isValid = true;foreach (var (dx, dy) in offsets){int checkX = x + dx;int checkY = y + dy;if (!region.IsPixelCovered(checkY, checkX)){isValid = false;break;}}// 合并连续区间if (isValid){if (currentStart == -1)currentStart = x;}else if (currentStart != -1){erodedIntervals.Add(new Interval(currentStart, x - 1));currentStart = -1;}}if (currentStart != -1)erodedIntervals.Add(new Interval(currentStart, interval.End));}if (erodedIntervals.Count > 0)result[y] = MergeIntervals(erodedIntervals);});return new HRegion { _rleData = new Dictionary<int, List<Interval>>(result) };}// 单步矩形腐蚀(分离为水平+垂直)private HRegion ErosionRectSingleStep(HRegion region, int radius){// 水平腐蚀(1x(2r+1)矩形)var horiEroded = ErosionRect1D(region, radius, 0);// 垂直腐蚀((2r+1)x1矩形)var vertEroded = ErosionRect1D(horiEroded, 0, radius);return vertEroded;}// 一维矩形腐蚀(高效实现)private HRegion ErosionRect1D(HRegion region, int radiusX, int radiusY){var result = new ConcurrentDictionary<int, List<Interval>>();int totalRadius = radiusX + radiusY;Parallel.ForEach(region._rleData.Keys, y =>{var erodedIntervals = new List<Interval>();foreach (var interval in region._rleData[y]){int start = interval.Start + radiusX;int end = interval.End - radiusX;if (start > end) continue;// 检查垂直方向bool isValid = true;for (int dy = -radiusY; dy <= radiusY; dy++){int checkY = y + dy;if (!region.IsIntervalCovered(checkY, start, end)){isValid = false;break;}}if (isValid)erodedIntervals.Add(new Interval(start, end));}if (erodedIntervals.Count > 0)result[y] = MergeIntervals(erodedIntervals);});return new HRegion { _rleData = new Dictionary<int, List<Interval>>(result) };}// 预计算圆形结构元素偏移量private List<(int dx, int dy)> PrecomputeCircleOffsets(int radius){var offsets = new List<(int, int)>();int r2 = radius * radius;for (int dy = -radius; dy <= radius; dy++)for (int dx = -radius; dx <= radius; dx++)if (dx * dx + dy * dy <= r2)offsets.Add((dx, dy));return offsets;}// 合并重叠/相邻区间private List<Interval> MergeIntervals(List<Interval> intervals){if (intervals.Count == 0) return intervals;var merged = new List<Interval> { intervals[0] };for (int i = 1; i < intervals.Count; i++){var last = merged[merged.Count - 1];if (intervals[i].Start <= last.End + 1)merged[merged.Count - 1] = new Interval(last.Start, Math.Max(last.End, intervals[i].End));elsemerged.Add(intervals[i]);}return merged;}// 形态学操作 - 腐蚀// 形态学操作 - 腐蚀(支持圆形和矩形结构元素)public HRegion Erosion(int radius, bool useCircle = true){HRegion result = new HRegion();foreach (var kvp in _rleData){int y = kvp.Key;foreach (var interval in kvp.Value){// 初始候选区间(先应用半径的简单收缩)int candidateStart = interval.Start + radius;int candidateEnd = interval.End - radius;if (candidateStart > candidateEnd) continue;// 检查候选区间内的每个点List<Interval> validIntervals = new List<Interval>();int currentStart = -1;int currentEnd = -1;for (int x = candidateStart; x <= candidateEnd; x++){bool isValid = true;if (useCircle){// 圆形结构元素检查for (int dy = -radius; dy <= radius; dy++){for (int dx = -radius; dx <= radius; dx++){// 检查是否在圆形内if (dx * dx + dy * dy <= radius * radius){int checkX = x + dx;int checkY = y + dy;if (!HasPixel(checkY, checkX, checkX)){isValid = false;break;}}}if (!isValid) break;}}else{// 矩形结构元素检查for (int dy = -radius; dy <= radius; dy++){for (int dx = -radius; dx <= radius; dx++){int checkX = x + dx;int checkY = y + dy;if (!HasPixel(checkY, checkX, checkX)){isValid = false;break;}}if (!isValid) break;}}// 处理连续的有效区间if (isValid){if (currentStart == -1){currentStart = x;currentEnd = x;}else if (x == currentEnd + 1){currentEnd = x;}else{validIntervals.Add(new Interval(currentStart, currentEnd));currentStart = x;currentEnd = x;}}}// 添加最后一个区间if (currentStart != -1){validIntervals.Add(new Interval(currentStart, currentEnd));}// 将有效区间添加到结果中if (validIntervals.Count > 0){if (!result._rleData.TryGetValue(y, out var resultIntervals)){resultIntervals = new List<Interval>();result._rleData[y] = resultIntervals;}resultIntervals.AddRange(validIntervals);}}}// 对每行的区间进行合并和排序foreach (var intervals in result._rleData.Values){intervals.Sort((a, b) => a.Start.CompareTo(b.Start));// 合并重叠或相邻的区间for (int i = 0; i < intervals.Count - 1;){if (intervals[i].End + 1 >= intervals[i + 1].Start){intervals[i] = new Interval(Math.Min(intervals[i].Start, intervals[i + 1].Start),Math.Max(intervals[i].End, intervals[i + 1].End));intervals.RemoveAt(i + 1);}else{i++;}}}result._boundingBoxValid = false;return result;}/// <summary>/// 检查指定像素 (x,y) 是否被当前区域覆盖/// </summary>/// <param name="y">行坐标</param>/// <param name="x">列坐标</param>/// <returns>true如果像素在区域内</returns>public bool IsPixelCovered(int y, int x){// 1. 检查该行是否存在数据if (!_rleData.TryGetValue(y, out var intervals))return false;// 2. 二分查找优化:快速定位x可能所在的区间int left = 0;int right = intervals.Count - 1;while (left <= right){int mid = (left + right) / 2;var interval = intervals[mid];if (x < interval.Start){right = mid - 1;}else if (x > interval.End){left = mid + 1;}else{return true; // x在区间[Start, End]内}}return false;}/// <summary>/// 检查指定行y上的区间[start, end]是否完全被覆盖/// </summary>public bool IsIntervalCovered(int y, int start, int end){if (!_rleData.TryGetValue(y, out var intervals))return false;// 遍历所有区间,检查是否有一个区间完全包含[start, end]foreach (var interval in intervals){if (interval.Start <= start && interval.End >= end)return true;// 区间已排序,如果当前区间.Start > end,后续不可能有覆盖if (interval.Start > end)break;}return false;}// 开运算 = 先腐蚀后膨胀public HRegion Opening(int radius){return Erosion(radius).Dilation(radius);}// 闭运算 = 先膨胀后腐蚀public HRegion Closing(int radius){return Dilation(radius).Erosion(radius);}// 连通域分析public static List<HRegion> Connection(HRegion region){List<HRegion> connectedRegions = new List<HRegion>();if (region._rleData.Count == 0) return connectedRegions;// 使用并查集算法标记连通区域Dictionary<Point, int> labels = new Dictionary<Point, int>();int currentLabel = 1;UnionFind uf = new UnionFind();// 第一遍扫描: 分配临时标签foreach (var kvp in region._rleData){int y = kvp.Key;foreach (var interval in kvp.Value){for (int x = interval.Start; x <= interval.End; x++){Point p = new Point(x, y);// 检查相邻像素的标签List<int> neighborLabels = new List<int>();// 左邻if (labels.TryGetValue(new Point(x - 1, y), out int leftLabel))neighborLabels.Add(leftLabel);// 上邻if (labels.TryGetValue(new Point(x, y - 1), out int topLabel))neighborLabels.Add(topLabel);if (neighborLabels.Count == 0){// 新标签int newLabel = currentLabel++;labels[p] = newLabel;uf.MakeSet(newLabel);}else{// 使用最小的邻居标签int minLabel = neighborLabels.Min();labels[p] = minLabel;// 合并等价类foreach (var label in neighborLabels){if (label != minLabel)uf.Union(minLabel, label);}}}}}// 第二遍扫描: 分配最终标签并收集区域Dictionary<int, HRegion> labelToRegion = new Dictionary<int, HRegion>();foreach (var kvp in labels){Point p = kvp.Key;int label = uf.Find(kvp.Value);if (!labelToRegion.TryGetValue(label, out HRegion connectedRegion)){connectedRegion = new HRegion();labelToRegion[label] = connectedRegion;}if (!connectedRegion._rleData.TryGetValue(p.Y, out var intervals)){intervals = new List<Interval>();connectedRegion._rleData[p.Y] = intervals;}// 尝试合并相邻的像素bool merged = false;for (int i = 0; i < intervals.Count; i++){if (intervals[i].End + 1 == p.X){intervals[i] = new Interval(intervals[i].Start, p.X);merged = true;break;}else if (intervals[i].Start - 1 == p.X){intervals[i] = new Interval(p.X, intervals[i].End);merged = true;break;}}if (!merged){intervals.Add(new Interval(p.X, p.X));// 保持区间有序intervals.Sort((a, b) => a.Start.CompareTo(b.Start));}}// 更新每个连通区域的边界框foreach (var r in labelToRegion.Values){r.UpdateBoundingBox();connectedRegions.Add(r);}return connectedRegions;}// 并查集数据结构用于连通域分析private class UnionFind{private Dictionary<int, int> parent = new Dictionary<int, int>();private Dictionary<int, int> rank = new Dictionary<int, int>();public void MakeSet(int x){parent[x] = x;rank[x] = 0;}public int Find(int x){if (parent[x] != x)parent[x] = Find(parent[x]);return parent[x];}public void Union(int x, int y){int xRoot = Find(x);int yRoot = Find(y);if (xRoot == yRoot) return;if (rank[xRoot] < rank[yRoot])parent[xRoot] = yRoot;else if (rank[xRoot] > rank[yRoot])parent[yRoot] = xRoot;else{parent[yRoot] = xRoot;rank[xRoot]++;}}}}
}
测试代码
运行速度在300ms左右,有点儿慢
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using Image = System.Drawing.Image;
using System.Diagnostics; // 添加Stopwatch命名空间namespace view3d
{public partial class MainForm : Form{HRegion region = new HRegion();Bitmap image;public MainForm(){InitializeComponent();}private void load_Click(object sender, EventArgs e){var stopwatch = Stopwatch.StartNew(); // 开始计时// 创建打开文件对话框OpenFileDialog openFileDialog = new OpenFileDialog();// 设置文件过滤器(只显示图片文件)openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";// 设置对话框标题openFileDialog.Title = "选择要加载的图片";// 显示对话框并检查用户是否点击了确定if (openFileDialog.ShowDialog() == DialogResult.OK){try{Image loadedImage = Image.FromFile(openFileDialog.FileName);// 从文件路径创建Image对象image = new Bitmap(loadedImage);string v1 = textBox1.Text;string v2 = textBox2.Text;byte i1 = byte.Parse(v1);byte i2 = byte.Parse(v2);region.FromBitmap((Bitmap)image, i1, i2);// 将图片显示到pictureBox1pictureBox1.Image = region.ToBitmap((Bitmap)image, Color.White);// 设置PictureBox的SizeMode为Zoom,使图片适应控件大小pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;stopwatch.Stop(); // 停止计时MessageBox.Show($"图片加载和处理耗时: {stopwatch.ElapsedMilliseconds} 毫秒", "耗时统计");}catch (Exception ex){// 如果加载失败,显示错误信息MessageBox.Show("加载图片时出错: " + ex.Message, "错误",MessageBoxButtons.OK, MessageBoxIcon.Error);}}}private void pictureBox1_Click(object sender, EventArgs e){}private void connection_Click(object sender, EventArgs e){var stopwatch = Stopwatch.StartNew(); // 开始计时List<HRegion> conns = HRegion.Connection(region);using (Graphics g = Graphics.FromImage(image)){g.Clear(Color.Black);}// 预定义一组颜色,或者随机生成颜色Color[] colors = new Color[]{Color.Red,Color.Green,Color.Blue,Color.Yellow,Color.Magenta,Color.Cyan,Color.Orange,Color.Purple,Color.Lime,Color.Pink};for (int i = 0; i < conns.Count; i++){HRegion region = conns[i];if (region != null){// 使用循环索引选择颜色,如果超过预定义颜色数量则随机生成Color regionColor = i < colors.Length ? colors[i] : GetRandomColor();region.ToBitmap(image, regionColor, false);}}stopwatch.Stop(); // 停止计时MessageBox.Show($"连通域分析耗时: {stopwatch.ElapsedMilliseconds} 毫秒", "耗时统计");// 刷新显示pictureBox1.Invalidate();}// 辅助方法:生成随机颜色private Color GetRandomColor(){Random rand = new Random();return Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));}private void Dilation_Click(object sender, EventArgs e){var stopwatch = Stopwatch.StartNew(); // 开始计时string v1 = textBox1.Text;string v2 = textBox2.Text;byte i1 = byte.Parse(v1);byte i2 = byte.Parse(v2);region = region.Dilation(i2);region.ToBitmap(image, Color.Yellow);stopwatch.Stop(); // 停止计时MessageBox.Show($"膨胀操作耗时: {stopwatch.ElapsedMilliseconds} 毫秒", "耗时统计");// 刷新显示pictureBox1.Invalidate();}private void button2_Click(object sender, EventArgs e){var stopwatch = Stopwatch.StartNew(); // 开始计时string v1 = textBox1.Text;string v2 = textBox2.Text;byte i1 = byte.Parse(v1);byte i2 = byte.Parse(v2);region = region.ErosionOptimized(i2);region.ToBitmap(image, Color.Green);stopwatch.Stop(); // 停止计时MessageBox.Show($"腐蚀操作耗时: {stopwatch.ElapsedMilliseconds} 毫秒", "耗时统计");// 刷新显示pictureBox1.Invalidate();}}
}
测试demo下载
见资源标定
相关文章:
c#实现halcon的rle编码blob分析
效果展示 实现功能 connection膨胀腐蚀开运算闭运算特征计算 核心代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.Linq;namespace view3d {// 基础对象类,类似于 Halcon 的 HO…...
python基于微信小程序的广西文化传承系统
文章目录 具体实现截图本项目支持的技术路线源码获取详细视频演示:文章底部获取博主联系方式!!!!本系统开发思路进度安排及各阶段主要任务java类核心代码部分展示主要参考文献:源码获取/详细视频演示 ##项目…...
Apache Flink深度解析:现代流处理引擎
好的,我来帮您写一篇关于Flink技术的详细介绍博客: Apache Flink深度解析:现代流处理引擎 一、Flink简介 Apache Flink是一个开源的分布式流处理和批处理统一计算引擎。它提供了数据流上的状态计算、精确一次性语义保证、高吞吐、低延迟等特性,能够运行在所有常见的集群…...
跨平台后端编程ASP.NET CORE Razor新一代Web开发框架C#
asp.net core Razor动态语言编程代替asp.net .aspx更高级吗? https://blog.csdn.net/xiaoyao961/article/details/148846065 C#Blazor应用-跨平台WEB开发VB.NET-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148846437 Products.razor文件,Blazor和…...
【开源工具】一键解决使用代理后无法访问浏览器网页问题 - 基于PyQt5的智能代理开关工具开发全攻略
🌐【开源工具】一键解决使用代理后无法访问浏览器网页问题 - 基于PyQt5的智能代理开关工具开发全攻略 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代…...
uniapp安卓GPIO电平控制
模块简介 本模块为 UniApp 提供了对 Android 系统下 GPIO 的访问能力,支持导出、设置方向、读写电平值等操作。适用于 Android 架构设备(如 RK3288 平台)。 支持功能 功能方法名说明初始化 GPIO 方向initGpio({gpio, direction})设置 GPIO…...
苹果芯片macOS安装版Homebrew(亲测)
在Linux服务器上安装一个软件常用yum,apt、dnf命令,同样macOS可以使用brew命令来安装软件。 brew会自动帮你下载、解压、安装和配置,更重要的是:它还会自动处理好软件之间的依赖关系,它将所有软件都安装在独立的统一目…...
vue | vue-macros 插件升级以及配置
Vue Macros 是一个为 Vue.js 提供更多宏和语法糖的开源项目vue-macros/vue-macros: Explore and extend more macros and syntax sugar to Vue. 问题:npm run build-only 打包时,报错:[Vue] Load plugin failed: vue-macros/volar 排查发现…...
计算机网络:(六)超详细讲解数据链路层 (附带图谱表格更好对比理解)
计算机网络:(六)超详细讲解数据链路层 前言一、数据链路层1. 数据链路层是什么?2. 哪些设备需要数据链路层?3. 数据链路层如何工作?4. 数据链路层的俩种信道4.1 点对点信道:一对一4.2 广播信道&…...
智能生成分析报告系统在危化安全生产监测预警评估中的应用
一、引言 在危险化学品安全生产监管中,传统的分析报告依赖人工整理与审核,效率低、响应慢,且极易受到主观判断、格式不规范、不同地区掌握尺度不一致的影响。而随着工业互联网、大数据、人工智能(AI)特别是大语言模型…...
微算法科技(NASDAQ:MLGO)研发可信共识算法TCA,解决区块链微服务中的数据一致性与安全挑战
随着区块链技术的不断演进和应用场景的拓展,微服务架构因其灵活性、可扩展性以及易于维护的特点,逐渐成为了构建复杂系统的首选架构模式。如何在微服务架构中有效应用区块链技术,确保数据的一致性和安全性,成为了一个亟待解决的问…...
UE5 开发遇到的bug整理
文章目录 一、人物在挂载某个Actor之后,移动有问题,可能是Actor类的碰撞没有关闭,和人物自身发生了碰撞。 一、人物在挂载某个Actor之后,移动有问题,可能是Actor类的碰撞没有关闭,和人物自身发生了碰撞。...
单片机——浮点数转换4位数码管显示
浮点数转换4位数码管显示 static char buffer[5]; int DecimalPlace 0; #define HideChar h void DisplayFloatOn4LED(float value) {long integer roundf(value );if (integer > 9999) //4位{integer 9999;snprintf(buffer, sizeof(buffer), "%4ld", integer…...
广东省专升本英语形容词与副词全梳理
一、形容词核心知识详解 (一)形容词的构成方式(附记忆技巧) 1. 后缀派生法(9 大核心后缀) ① -ly 结尾形容词(易混副词,重点记忆) ✅ 特点:虽以 - ly 结尾…...
GeoServer和GeoTools XML外部实体注入漏洞(CVE-2025-30220)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
Python Django全功能框架开发秘籍
本文在创作过程中借助 AI 工具辅助资料整理与内容优化。图片来源网络。 文章目录 引言一、Django 简介1.1 Django 的诞生与背景1.2 Django 的特点概述 二、Django 的核心特性2.1 ORM 特性2.1.1 ORM 原理与优势2.1.2 ORM 在实际应用中的优势 2.2 模板引擎2.2.1 模板引擎的工作机…...
四核 A53+工业级存储:移远 SC200L 与 pSLC SD NAND 如何重构 T-BOX 性能边界?
博客目录 一、移远 SC200L:T-BOX 的 “智慧大脑”二、米客方德 MKDN064GIL-ZA T-BOX:数据安全的坚固堡垒三、深度协同:拓展 T-BOX 应用边界 在车联网浪潮席卷而来的当下,T-BOX 作为汽车与外界交互的核心枢纽,其性能优劣…...
docker方式启动Jenkins
docker方式启动Jenkins 1.启动命令 我已经打包好了文件,如下命令即可启动 docker run -d -v jenkins_home:/var/jenkins_home -p 8088:8080 -p 50000:50000 --restarton-failure registry.cn-hangzhou.aliyuncs.com/devops_de/jenkins:lts-jdk17 还需要设置一下目录权限,要…...
【目标检测】图像处理基础:像素、分辨率与图像格式解析
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
国产免费的k8s管理平台
xkube是一款永久免费且无任何功能限制的k8s集群管理平台,提供PC端和移动端全平台支持,具备完善的集群管理、运维监控和CI/CD发布功能,让企业轻松实现跨集群的统一管理和自动化运维。 技术特点: 1、xkube是一款国产永久免费的k8s…...
火山引擎大模型未来发展趋势
用户可能正在做技术选型或者行业研究,需要预测火山引擎在激烈竞争中的突围方向。从问题简洁性看,ta可能已经有一定基础认知,不需要我从零科普大模型概念。 火山引擎作为字节跳动的技术输出平台,优势在于背靠抖音、今日头条等超级应…...
Java基础(三):逻辑运算符详解
Java基础系列文章 Java基础(一):发展史、技术体系与JDK环境配置详解 Java基础(二):八种基本数据类型详解 Java基础(三):逻辑运算符详解 目录 一、什么是逻辑运算符?二、基础逻辑运算符(3种)1、&&…...
设计模式 | 单例模式
单例模式(Singleton Pattern) 是设计模式中最简单却最常用的模式之一,它确保一个类只有一个实例,并提供全局访问点。本文将深入探讨单例模式的核心思想、实现技巧以及在C中的多种实现方式。 为什么需要单例模式? 在软…...
SQL_Server 基本语法
1.创建数据库 use master go if exists(select * from sysdatabases where nameCourseManageDB) drop database CourseManageDB go --创建数据库 create database CourseManageDB on primary (--数据库的逻辑文件名(就是系统用的,必须唯一)…...
剑指offer39_连续子数组的最大和
连续子数组的最大和 输入一个 非空 整型数组,数组里的数可能为正,也可能为负。 数组中一个或连续的多个整数组成一个子数组。 求所有子数组的和的最大值。 要求时间复杂度为 O ( n ) O(n) O(n)。 数据范围 数组长度 [ 1 , 1000 ] [1,1000] [1,100…...
SPL 实践系列:跨库移植 SQL
背景 应用程序可能要基于不同数据库工作,各种数据库的 SQL 语法大体一致,但仍有些差别,结果就要改造这些 SQL,而这事通常只能手工调整,工作量大还容易出错。 完全自动改造 SQL 几乎是无法做到的,毕竟各种…...
docker启动的rabbitmq搭建并集群和高可用
Docker 搭建 RabbitMQ 集群步骤 以下是使用 Docker 快速搭建 RabbitMQ 集群的详细步骤,包含配置文件、网络设置和集群组建过程。 1. 创建自定义网络 首先创建一个 Docker 网络,使容器间可以通过名称互相访问: docker network create rabb…...
ISCSI存储
ISCSI存储 一、iscsi简介 1. 基本概念 iSCSI(Internet Small Computer System Interface)即互联网小型计算机系统接口,它是一种基于 TCP/IP 协议的存储网络协议,将传统的 SCSI(Small Computer System Interface&…...
算法与数据结构:动态规划DP
文章目录 动态规划算法全面解析一、核心思想与基本概念二、动态规划与其他算法的区别三、动态规划的解题步骤四、经典案例解析1. **斐波那契数列(Fibonacci)**2. **0-1背包问题(0-1 Knapsack)**3. **最长公共子序列(LC…...
核心概念解析:AI、数据挖掘、机器学习与深度学习的关系
核心概念解析:AI、数据挖掘、机器学习与深度学习的关系 本节旨在厘清人工智能(AI)、机器学习(ML)、深度学习(DL)、数据挖掘等常被混淆的概念及其相互关系。 1. 从应用目标看:人工智…...
跨域视角下强化学习重塑大模型推理:GURU框架与多领域推理新突破
跨域视角下强化学习重塑大模型推理:GURU框架与多领域推理新突破 大语言模型(LLM)推理能力的提升是AI领域的重要方向,强化学习(RL)为此提供了新思路。本文提出的GURU框架,通过构建跨领域RL推理语…...
黑马python(十三)
目录: 1.文件编码概念 2.文件的读取操作 3.文件的写入操作 4.文件的追加写操作 5.文件操作的综合案例 1.文件编码概念 2.文件的读取操作 多次调用read或相关读取方法会接着上一次读取的记录读 如果文件没有关闭,只要程序还在运行,文件…...
Redis-CPP 5大类型操作
这篇文章不会讲解所有关于5大基础类型的所有命令,只讲解几个常用的命令操作。如果想看全部的命令操作,可以看其它的文章。 string set 先来看一看set操作在服务器端的函数原型: SET key value [expiration EX seconds|PX milliseconds] [N…...
Linux 下的 socket
1、简介 Socket,中文常称为“套接字”,是 UNIX 操作系统中引入的一种通信抽象接口,用于支持不同进程之间,特别是不同主机之间的通信。在 UNIX 哲学中,“一切皆文件”,包括网络通信也不例外。Socket 就是这种…...
链接脚本基础语法
目录 前言 ELF文件布局 链接脚本语法 段定义标准格式 地址计数器 . 地址计数器的动态特性 赋值 vs 引用 符号定义 通配符规则 COMMON块 COMMON 块的产生与处理 示例脚本 前言 由于嵌入式系统内存资源珍贵,链接脚本可指定代码段(.text &#…...
Python期末速成
一.基础内容 赋值语句: a 1 b "mayday" 标识符规则: 1.字母,数字,下划线,汉字组成。但数字不能开头 2.不能是保留字 3.特殊符号不行,*¥^等 注释是在语句前面加# …...
Python打卡训练营Day56
DAY 56 时序数据的检验 知识点回顾: 假设检验基础知识 原假设与备择假设P值、统计量、显著水平、置信区间 白噪声 白噪声的定义自相关性检验:ACF检验和Ljung-Box 检验偏自相关性检验:PACF检验 平稳性 平稳性的定义单位根检验 季节性检验 ACF检…...
没掌握的知识点记录
1、微内核的主要优点在于结构清晰、内核代码量少,安全性和可靠性高、可移植性强、可伸缩性、可扩展性高;其缺点是难以进行良好的整体优化、进程间互相通信的开销大、内核功能代码不能被直接调用而带来服务的效率低。 2、题目: 分页内存管理…...
Python商务数据分析——Python 入门基础知识学习笔记
一、简介 1.1 Python 特性 解释型语言:代码无需编译可直接运行,适合快速开发。 动态类型:变量类型在运行时确定(如x1后x"str"仍合法)。 面向对象:支持类、对象、继承等特性,代码可…...
企业级安全实践:SSL 加密与权限管理(二)
权限管理:企业数据的守护者 权限管理的基本概念与重要性 权限管理,是指根据系统设置的安全规则或策略,用户可以访问且仅能访问自己被授权的资源,不多不少 。它是企业信息安全体系的重要组成部分,旨在确保只有授权的人…...
JavaScript 的 “==” 存在的坑
(双等) 指的是宽松相等 — 会做隐式类型转换 举例:0 // true 5 5 // true (三等) 指的是严格相等 — 类型和值都相等才 true 举例:0 // false 5 5 // false 在业务逻辑里经常因为隐式转换导致条件误判,业界普遍推荐 一律用 / !。 举…...
深度解析云计算网络架构:VLAN+OVS+Bonding构建高可靠虚拟化平台
——从物理设备到虚拟机流量的全链路剖析 核心技术组合:VLAN逻辑隔离 OVS虚拟交换 Bonding链路聚合 超融合网络管理 一、架构全景:物理与虚拟网络的协同(附架构图) 核心设计哲学 #mermaid-svg-VbGP3fCgNnoLVMgH {font-family:&…...
Git使用总结
1.基本概念: Git中的区域: git中有几个区域;本地工作区;本地提交区;origin远端。 一般来说的工作上传顺序是: 将修改文件添加到工作区域----提交到本地提交区域----push到远端分支 Git中的分支 远端和…...
爬虫入门练习(文字数据的爬取)
爬取csdn用户的用户简介 学习一下 BeautifulSoup方法 from bs4 import BeautifulSoup html_content """ <html> <head><title>示例网页</title> </head> <body><h1 class"main-title">欢迎学习Beauti…...
MySQL学习(1)——基础库操作
欢迎来到博主的专栏:MySQL学习 博主ID:代码小豪 文章目录 数据库原理基础库操作增删数据库数据库编码与校验规则验证不同的校验规则对于库中数据的影响 备份与恢复数据库 数据库原理 mysql版本:mysql8.0 操作系统:ubuntu22.4 为了减少由于环境配置以及权限限制带来的使用问题&…...
P99延迟:系统性能优化的关键指标
理解P99延迟 当谈论系统性能时,延迟指标扮演着至关重要的角色。其中,P99延迟作为最重要的性能指标之一,能够帮助我们识别系统的性能瓶颈,优化用户体验。 构建一个功能完善的后端系统,通过了所有功能测试,准…...
人工智能、机器人最容易取哪些体力劳动和脑力劳动
人工智能、机器人最容易取哪些体力劳动和脑力劳动 人工智能和机器人的发展可以替代人类简单的体力劳动和脑力劳动,但很难替代复杂的体力劳动和脑力劳动。 肌肉收缩的原理和运动特点 人类的体力劳动是靠肌肉的收缩完成的,其工作原理是肌肉内的肌球蛋白…...
【代码解析】opencv 安卓 SDK sample - 1 - HDR image
很久没有写安卓了,复习复习。用的是官方案例,详见opencv-Android-sdk 包 // 定义包名,表示该类的组织路径 package org.opencv.samples.tutorial1;// 导入所需的OpenCV和Android类库 import org.opencv.android.CameraActivity; // OpenCV…...
管理综合知识点
比与比例涉及的问题 比与比例基础知识比例的转换正反比例浓度问题利润问题增长率问题比例与面积行程问题 一、比例转换与性质 核心公式: 若 a : b c : d a:b c:d a:bc:d或 a b c d \frac{a}{b} \frac{c}{d} badc → a d b c ad bc adbc(交…...
机器学习:特征向量与数据维数概念
特征向量与数据维数概念 一、特征向量与维数的定义 特征向量与特征类别 在机器学习和数据处理中,每个样本通常由多个特征(Feature) 描述。例如,一张图片的特征可能包括颜色、形状、纹理等;一个客户的特征可能包括年龄…...