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

OpenCV——霍夫变换

霍夫变换

  • 一、霍夫变换原理
  • 二、霍夫线检测
    • 2.1、标准霍夫变换
    • 2.2、概率霍夫变换
  • 三、霍夫圆检测
    • 3.1、霍夫圆检测的原理
    • 3.2、霍夫梯度法

一、霍夫变换原理

霍夫变换(Hough TRansform)是从图像中识别几何图形的基本方法,由Paul Hough于1962年提出。最初霍夫变换只能用来检测直线,经过不断的改进,霍夫变换能识别任意形状(多为圆和椭圆等几何图形)。

在笛卡尔坐标系下,一条直线可以用斜率k和截距q表示,其公式如下:

y = kx + q

把k和q放到一个坐标空间表示时这个坐标空间就称为霍夫空间,如下:

在这里插入图片描述

关于霍夫空间有一下两条重要定理:

  1. 笛卡尔空间中的一条直线,对应于霍夫空间的一个点,反过来也成立
  2. 如果笛卡尔坐标中有若干个点共线,则这些点在霍夫空间中对应的直线相交于一点

在这里插入图片描述

这样,在笛卡尔空间寻找直线的问题,就可以转换为在霍夫空间寻找相交点的问题。但是,在将杂乱的点连接成直线时,会有许多种连接方法。此时应该如何选择呢?霍夫变换的基本方式是选择由尽可能多的直线汇成的点,(a)所示,笛卡儿坐标系中有4、B、C、D、E共5个点,如果按照每两点构成一条直线来画线,则会有很多线。现在将这5个点转换成霍夫空间的直线,如图 (b)所示。可以看出,最多直线形成的交点是 M点和N点,相交直线有3条,其余交点都只有2条直线相交,因此,最后检测到的直线就是 M点和N点在笛卡儿坐标中对应的直线,即 ACE和 BCD,如图©所示。

在这里插入图片描述

上述方法简洁明了,但是有一个缺陷:当直线平行于y轴时斜率为无穷大,此时霍夫变换就遇到问题了。解决这个问题的方法是将笛卡儿坐标转换为极坐标。

在极坐标系中,任何直线可用p和0两个参数表示,公式如下:

p= xcos0 + ysin0

其中,p为原点到直线的垂直距离,0为直线垂线与x轴的夹角,如图所示。
在这里插入图片描述

这样,极坐标中的点也能对应于霍夫空间的线,只不过这时霍夫空间的参数不再是斜率k和截距 q,而是p和 0。极坐标中一条直线上的点,在霍夫空间中仍然交于一点,如图 10-5所示。
在这里插入图片描述

二、霍夫线检测

基于上述原理,霍夫线检测算法需要创建一个二维数组,称为累加器,如图 所示。检测结果的准确度取决于累加器的大小;如果希望角度精确到1°,则数组需要 180 列;p 的最大值为图片的对角线距离,如果希望 p精确度达到像素级别,则行数需要与对角线像素数一样。累加器统计直线交点次数的过程称为“投票”。投票开始后,对于图像中直线上的每像素(x,y),将其代入极坐标公式中,然后分别计算日各个值(如精度为 1°,则0为 0°,1°,2°,3°,…,180°)时的p值,如果累加器中有这个值,则给这个值投一票,对所有像素投完票后,找到累加器中的最大值对应的p和0,这两个参数对应的直线就是检测结果。

在这里插入图片描述

OpenCV 中的霍夫变换函数不止一个,下面介绍标准霍夫变换函数(SHT)和概率霍夫变换函数(PPHT)。

2.1、标准霍夫变换

//用标准霍夫变换在二值图像中寻找直线
void Imgproc.HoughLines(Mat image, Mat lines, double rho, double theta, int threshold)
  • image:8位单通道二值图像
  • lines:检测到的直线(二维数组),每条直线由p和0表示
  • rho:累加器中距离的精度,单位为像素
  • theta:累加器中角度的精度,单位为弧度
  • threshold:累加器中的阈值参数,只有获得足够多投票的直线才出现在结果集中
public class HoughLines {static {OpenCV.loadLocally(); // 自动下载并加载本地库}public static void main(String[] args) {//读取图像并显示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/board.jpg");HighGui.imshow("src", src);HighGui.waitKey(0);//Canny边缘检测并将结果存储为BGR图像Mat canny = new Mat();Mat dst = new Mat();Imgproc.Canny(src, canny, 50, 200, 3, false);Imgproc.cvtColor(canny, dst, Imgproc.COLOR_GRAY2BGR);//进行霍夫线检测,结果在lines中Mat lines = new Mat();Imgproc.HoughLines(canny, lines, 1, Math.PI / 180, 150);//将检测结果用红线画出for (int n = 0; n < lines.rows(); n++) {double rho = lines.get(n, 0)[0];//极坐标中的pdouble theta = lines.get(n, 0)[1];//极坐标中的θdouble cos = Math.cos(theta);double sin = Math.sin(theta);double x0 = cos * rho;double y0 = sin * rho;double len = 800;//所画直线长度Point pt1 = new Point(Math.round(x0 + len * (-sin)), Math.round(y0 + len * (cos)));Point pt2 = new Point(Math.round(x0 - len * (-sin)), Math.round(y0 - len * (cos)));Imgproc.line(dst, pt1, pt2, new Scalar(0, 0, 255), 3);}//显示HighGui.imshow("Detected Lines", dst);HighGui.waitKey(0);System.exit(0);}
}

原图:
在这里插入图片描述

霍夫线检测结果:
在这里插入图片描述

程序中有一个变量len 是指画线的长度,因为标准霍夫变换中输出的是直线的p和0,而根据这两个参数得到的是直线(没有起始点和终止点)而不是线段,所以需要指定线的长度。由于原图像的宽和高都低于 800 像素,所以将长度设为800。如果检测图像的分辨率较高,则需要调整直线的长度。

在这里插入图片描述

在这里插入图片描述

上述程序中由于用的图像相对简单,所以结果也比较完美,但是如果更换一下输入图像,则结果可能会出人意料。接下来把输入图像换成稍微复杂点的图像:有黑白棋子的棋盘。这样的结果似乎很不理想,主要问题有两个。一是棋盘上有的地方明明只有一条线,但检测结果却变成了一组线,而且角度相差很小。另一个问题是有几条斜线是原图像中没有的。如果仔细检査一下代码,则可以发现问题的根源所在。

第1 个问题出在 HoughLines(函数的第 4 个参数 theta 上。程序中将其设为 Math.P/180,换算成角度就是 1°。由于霍夫线检测是根据阈值判断是否是直线的,水平方向的棋盘线自然毫无问题地被判断成直线,但在测试稍许倾斜的直线时,也能符合阈值要求,因而也被判断为直线。

第2个问题和霍夫线检测的原理有关。霍夫线检测实际上是统计霍夫空间中交点的数量而不管相关像素是否连续,因而即使是肉眼看上去相隔很远的像素,只要交点数量超过阈值仍然会被判断为直线。观察原图像可以看出,斜线出现处都是棋子比较密集的地方,这些斜线无一例外地都经过多枚棋子的边缘像素。这些像素虽然并不连续,但在投票时无疑会被统计在内,最后因为超过阈值而被检测为直线。解决这个问题的方法是把阈值提高,这样不连续的像素就不会构成直线了。

public class HoughLines2 {static {OpenCV.loadLocally(); // 自动下载并加载本地库}public static void main(String[] args) {//读取图像并显示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/chess.jpg");HighGui.imshow("src", src);HighGui.waitKey(0);//Canny边缘检测并将结果存储为BGR图像Mat canny = new Mat();Mat dst = new Mat();Imgproc.Canny(src, canny, 50, 200, 3, false);Imgproc.cvtColor(canny, dst, Imgproc.COLOR_GRAY2BGR);//进行霍夫线检测,结果在lines中Mat lines = new Mat();Imgproc.HoughLines(canny, lines, 1, Math.PI / 30, 300);//将检测结果用红线画出for (int n = 0; n < lines.rows(); n++) {double rho = lines.get(n, 0)[0];//极坐标中的pdouble theta = lines.get(n, 0)[1];//极坐标中的θdouble cos = Math.cos(theta);double sin = Math.sin(theta);double x0 = cos * rho;double y0 = sin * rho;double len = 800;//所画直线长度Point pt1 = new Point(Math.round(x0 + len * (-sin)), Math.round(y0 + len * (cos)));Point pt2 = new Point(Math.round(x0 - len * (-sin)), Math.round(y0 - len * (cos)));Imgproc.line(dst, pt1, pt2, new Scalar(0, 0, 255), 3);}//显示HighGui.imshow("Detected Lines", dst);HighGui.waitKey(0);System.exit(0);}
}

将阈值提高到300,theta参数调整为 PI/30,最后检测结果符合预期:
在这里插入图片描述

2.2、概率霍夫变换

概率霍夫变换是标准霍夫变换的改进版。标准霍夫变换中输出的是直线的p和0,根据这两个参数得到的是直线(没有起始点和终止点)而不是线段,而概率霍夫变换则输出线段的起始点和终止点。也就是说,标准霍夫变换只输出方向,而概率霍夫变换则不仅输出方向,还输出范围。之所以称为“概率”霍夫变换,是因为这个算法并没有累加平面内的所有可能的点,而是随机选取一个点集进行计算。其理论依据是如果峰值足够高,则只用一小部分时间去寻找它就足够了,这样可以大大节省时间。

//用概率霍夫变换在二值图像中寻找直线
void Imgproc.HoughLinesP(Mat image, Mat lines, double rho, double theta, int rhreshold)
  • image:8位单通道二值图像
  • lines:检测到的直线(二维数组),每条直线由p和0表示
  • rho:累加器中距离的精度,单位为像素
  • theta:累加器中角度的精度,单位为弧度
  • threshold:累加器中的阈值参数,只有获得足够多投票的直线才出现在结果集中。这个值越大,所判断的直线越少,反之越多
public class HoughLinesP {static {OpenCV.loadLocally(); // 自动下载并加载本地库}public static void main(String[] args) {//读取图像并显示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/chess.jpg");HighGui.imshow("src", src);HighGui.waitKey(0);//Canny边缘检测并将结果存储为BGR图像Mat canny = new Mat();Mat dst = new Mat();Imgproc.Canny(src, canny, 50, 200, 3, false);Imgproc.cvtColor(canny, dst, Imgproc.COLOR_GRAY2BGR);//进行霍夫线检测,结果在lines中Mat lines = new Mat();Imgproc.HoughLinesP(canny, lines, 1, Math.PI / 180, 250);//将检测结果用红线画出for (int n = 0; n < lines.rows(); n++) {double[] vec = lines.get(n, 0);double x1 = vec[0], y1 = vec[1];//线段的端点1double x2 = vec[2], y2 = vec[3];//线段的端点2Point pt1 = new Point(x1, y1);Point pt2 = new Point(x2, y2);Imgproc.line(dst, pt1, pt2, new Scalar(0, 255, 255), 5);}//显示HighGui.imshow("Detected Lines", dst);HighGui.waitKey(0);System.exit(0);}
}

原图:
在这里插入图片描述

概率霍夫变换检测:
在这里插入图片描述

可以看出,概率霍夫变换与标准霍夫变换的结果有较大的不同。首先,概率霍夫变换检测的结果是线段,而不是直线。另外,概率霍夫变换只检测出了部分直线(线段),有相当一部分直线(线段)并未检测出来,因为它只是随机选择了一个点集进行计算,而没有计算所有像素。

三、霍夫圆检测

3.1、霍夫圆检测的原理

霍夫圆检测的原理和霍夫线检测类似,只是从霍夫线的二维变成了三维。在笛卡儿坐标系中圆的方程如下:

(x-a)^2 + (y-b)^2 = r^2

其中,(a,6)为圆心坐标,r为圆的半径,如图所示

在这里插入图片描述

由此可见,要表示一个圆需要 a、b、r 三个参数。在 a、b、r组成的三维坐标系中,一个点可以唯一确定一个圆。笛卡儿坐标系中经过某一点的所有圆映射到 abr 坐标系中是一条三维的曲线,如图 10-12 所示。

霍夫圆检测的过程和直线差不多,但三维空间的计算量比二维空间增加了很多倍,标准霍夫圆检测效率很低,所以 OpenCv 中使用霍夫梯度法进行圆形的检测。

3.2、霍夫梯度法

霍夫梯度法的原理并不复杂,如图 10-13 所示,圆心是圆周上众多法线的交汇点,霍夫梯度法就是据此来寻找圆心的。
在这里插入图片描述

霍夫梯度法检测圆的原理可用下面的例子说明。

在这里插入图片描述

假设图像上有4个点,分别为 A、B、C、D,已知这些点的梯度方向,求这些点构成的圆,如图 10-14(a)所示。
求解的过程如下:

  1. 沿4个点的梯度方向画出法线,发现它们相交于 O 点,那么 O点就是可能的圆心,如图 10-14(b)所示。
  2. 下一步是寻找半径,或者说验证各种半径的支持度。4 个点与O点的连线距离 OA、OB、OC、OD 分别为4种候选的半径,记为r、r2、r3、r4。
  3. 经计算发现r~r4中只有两种半径,其中r=r2=r3,统一记为r,而r比n要长。
  4. 现在统计各半径的支持度:r的支持度为 3,r的支持度为 1。
  5. 假设 3 超过累加器中设定的阈值,那么点 O 和半径, 就是要求解的圆的圆心和半径
  6. 根据点O和,画出的圆,如图 10-14(b)所示。

由上可知,霍夫梯度法大体分为两步,第1步是寻找候选圆心,第2步是根据非零像素对候选圆心的支持度来确定半径。在寻找圆心时,霍夫梯度法需要先对图像进行 Canny 边缘检测,然后用 Sobel函数求出局部梯度并画出法线,并通过累加器投票得出候选的圆心。接着,对每个候选圆心选择非零像素最支持的一条半径。如果一个候选圆心获得边缘图像非零像素最充分的支持,并且离其他圆心有足够的距离,则该圆心及半径所构成的圆成立。OpenCy 中霍夫圆检测的函数原型如下:

//用霍夫变换寻找圆
Imgproc.HoughCircles(Mat image, Mat circles, int method, double dp, double minDist, double param1, double param2, int minRadius, int maxRadius)
  • image:输入图像,要求是8位单通道灰度图
  • circles:检测到的圆
  • method:检测算法,目前只支持Imgproc.HOUGH_GRADIENT霍夫梯度算法
  • dp:霍夫空间的分辨率。当dp=1时,累加器的分辨率与输入图像相同;当dp=2时,累加器的分辨率(宽和高)是输入图像的一半
  • minDist:圆心之间的最小距离,如果检测到两个圆心距离小于该值,则认为它们是同一个圆心
  • param1:Canny边缘检测时的高阈值,低阈值是高阈值的一半
  • param2:检测圆心和确定半径时的累加器计数阈值
  • minRadius:检测到的圆半径的最小值
  • maxRadius:检测到的原半径的最大值。当MaxRadius<=0时表示采用图像的最大尺寸

夫梯度法解决了标准霍夫圆检测效率过低的问题,但是它存在如下缺陷:

  1. 霍夫梯度法中使用 Sobel 导数来计算局部梯度,但这并不是一个数值稳定的方法在某些情况下会产生噪声。
  2. 在边缘图像中的每个非零像素都是很多可能的圆上的点,如果累加阈值设置得过低,则会导致算法耗时过多。
  3. 霍夫梯度法中每个圆心只选择一个圆,这意味着如果有同心圆,就只能选择其中一个。
public class HoughCircle {static {OpenCV.loadLocally(); // 自动下载并加载本地库}public static void main(String[] args) {//读取图像并显示// Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/chess.jpg");Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/seeds.png");HighGui.imshow("src", src);HighGui.waitKey(0);//预处理Mat gray = new Mat();Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);Imgproc.GaussianBlur(gray, gray, new Size(9, 9), 2);//霍夫圆检测Mat circles = new Mat();Imgproc.HoughCircles(gray, circles, Imgproc.HOUGH_GRADIENT, 1, 10, 100, 30, 5, 30);//将检测出的圆画出for (int n = 0; n < circles.cols(); n++) {double[] c = circles.get(0, n);Point center = new Point(Math.round(c[0]), Math.round(c[1]));//圆心int radius = (int)Math.round(c[2]);//半径Imgproc.circle(src, center, radius, new Scalar(0, 0, 255), 5);}//显示HighGui.imshow("Circles", src);HighGui.waitKey(0);System.exit(0);}
}

原图1:
在这里插入图片描述

霍夫圆检测1:
在这里插入图片描述

原图2:
在这里插入图片描述

霍夫圆检测2:

在这里插入图片描述

鉴于霍夫梯度法的原理,最后检测出的圆可能和直观感觉有较大区别。有时图像中明明有较多的圆却无法检测出来;有时检测出的圆在我们看来根本就不是圆,因此,在利用霍夫梯度法检测圆时,应根据其原理选择合适的场景,否则结果往往不尽人意。

相关文章:

OpenCV——霍夫变换

霍夫变换 一、霍夫变换原理二、霍夫线检测2.1、标准霍夫变换2.2、概率霍夫变换 三、霍夫圆检测3.1、霍夫圆检测的原理3.2、霍夫梯度法 一、霍夫变换原理 霍夫变换&#xff08;Hough TRansform&#xff09;是从图像中识别几何图形的基本方法&#xff0c;由Paul Hough于1962年提…...

线程池 JMM 内存模型

线程池 & JMM 内存模型 文章目录 线程池 & JMM 内存模型线程池线程池的创建ThreadPoolExecutor 七大参数饱和策略ExecutorService 提交线程任务对象执行的方法&#xff1a;ExecutorService 关闭线程池的方法&#xff1a;线程池最大线程数如何确定&#xff1f; volatile…...

PillarNet: Real-Time and High-PerformancePillar-based 3D Object Detection

​ECCV 2022 paper&#xff1a;[2205.07403] PillarNet: Real-Time and High-Performance Pillar-based 3D Object Detection&#xfeff; code&#xff1a;https://github.com/VISION-SJTU/PillarNet-LTS&#xfeff; 纯点云基于pillar3D检测模型 网络比较 SECOND 基于vo…...

配电抢修场景案例

以配电抢修场景为例来展示关键业务活动。配电抢修愿景分成业务逻辑、业务活动、业务特征、技术支撑、KPI五个层次&#xff0c;分别从策略、执行、评价、资源、协同5个方面描述配电抢修愿景的关键业务活动。...

H5新增属性

✅ 一、表单相关新增属性&#xff08;Form Attributes&#xff09; 这些属性增强了表单功能&#xff0c;提升用户体验和前端验证能力。 1. placeholder 描述&#xff1a;在输入框为空时显示提示文本。示例&#xff1a; <input type"text" placeholder"请输…...

C# Task 模式实现 Demo(含运行、暂停、结束状态)

下面是一个完整的 C# Task 实现示例&#xff0c;包含运行(Running)、暂停(Paused)和结束(Completed)状态控制&#xff1a; 1. 基本实现&#xff08;使用 CancellationToken 控制&#xff09; using System; using System.Threading; using System.Threading.Tasks;public cla…...

Docker健康检查

目录 1.命令 2.验证 1.命令 docker run -itd --name nginx -v data:/etc/nginx/ -v log:/var/log/ -p 8080:80 \ --health-cmd"curl http://127.0.0.1:80" \ --health-interval30s \ --health-timeout5s \ --health-retries3 \ --health-start-period18s \ nginx:…...

Linux笔记---线程控制

1. 线程创建&#xff1a;pthread_create() pthread_create() 是 POSIX 线程库&#xff08;pthread&#xff09;中用于创建新线程的函数。调用该函数后系统就会启动一个与主线程并发的线程&#xff0c;并使其跳转到入口函数处执行。 #include <pthread.h>int pthread_cr…...

【AI论文】扩展大型语言模型(LLM)智能体在测试时的计算量

摘要&#xff1a;扩展测试时的计算量在提升大型语言模型&#xff08;LLMs&#xff09;的推理能力方面已展现出显著成效。在本研究中&#xff0c;我们首次系统地探索了将测试时扩展方法应用于语言智能体&#xff0c;并研究了该方法在多大程度上能提高其有效性。具体而言&#xf…...

Spring--IOC容器的一些扩展属性

一、BeanFactoryPostProcessor和BeanPostProcessor BeanFactoryPostProcessor的作用是在实例化前修改BeanDefinition的属性 BeanPostProcessor的作用是在bean完成创建实例、填充属性之后&#xff0c;初始化阶段的前后都会对bean进行操作&#xff0c;使用postProcessBeforeIni…...

WebClient 功能介绍,使用场景,完整使用示例演示

WebClient 功能介绍 WebClient 是 Spring 5 中引入的响应式 HTTP 客户端&#xff0c;用于替代已弃用的 RestTemplate&#xff0c;专为异步非阻塞编程设计&#xff0c;基于 Reactor 框架实现。其核心功能包括&#xff1a; 异步与非阻塞 通过 Mono 和 Flux 处理请求与响应&#…...

[Java 基础]ArrayList

ArrayList 类是一个可以动态修改的数组&#xff0c;与普通数组的区别就是它是没有固定大小的限制。 ArrayList 的示意可以看 VCR&#xff1a;https://visualgo.net/en/array 创建 ArrayList 对象 final ArrayList<String> strings new ArrayList<>();这里创建 …...

用无人机和AI守护高原净土:高海拔自然保护区的垃圾检测新方法

这篇题为《Automatic Detection of Scattered Garbage Regions Using Small Unmanned Aerial Vehicle Low-Altitude Remote Sensing Images for High-Altitude Natural Reserve Environmental Protection》的论文&#xff0c;发表于 Environmental Science & Technology&am…...

《Redis高并发优化策略与规范清单:从开发到运维的全流程指南》

Redis高并发优化策略与规范清单&#xff1a;从开发到运维的全流程指南 在互联网应用的后端架构中&#xff0c;Redis凭借其高性能、高并发的特性&#xff0c;成为缓存和数据存储的首选方案。无论是电商抢购、社交平台的点赞计数&#xff0c;还是在线旅游平台的实时数据查询&…...

Linux基本指令篇 —— man指令

man命令是Linux系统中最重要的命令之一&#xff0c;它是"manual"&#xff08;手册&#xff09;的缩写&#xff0c;用于查看Linux系统中命令、函数、配置文件等的详细说明文档。man命令是Linux系统管理员和开发者的必备工具&#xff0c;熟练掌握man命令可以大大提高工…...

Spring Boot使用MCP服务器

1、JDK版本17 2、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.apac…...

学习Linux进程冻结技术

原文&#xff1a;蜗窝科技Linux进程冻结技术 功耗中经常需要用到&#xff0c;但是linux这块了解甚少&#xff0c;看到这个文章还蛮适合我阅读的 1 什么是进程冻结 进程冻结技术&#xff08;freezing of tasks&#xff09;是指在系统hibernate或者suspend的时候&#xff0c;将…...

Docker基本概念——AI教你学Docker

1.1 Docker 概念详解 1. Docker 是什么&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;它让开发者可以将应用及其依赖打包到一个可移植的容器&#xff08;Container&#xff09;中&#xff0c;并在任何支持 Docker 的 Linux、Windows 或 macOS 系统上运行。这样做…...

第十六届蓝桥杯C/C++程序设计研究生组国赛 国二

应该是最后一次参加蓝桥杯比赛了&#xff0c;很遗憾&#xff0c;还是没有拿到国一。 大二第一次参加蓝桥杯&#xff0c;印象最深刻的是居然不知道1s是1000ms&#xff0c;花了很多时间在这题&#xff0c;后面节奏都乱了&#xff0c;抗压能力也不行&#xff0c;身体也不适。最后…...

Python 数据分析与可视化 Day 5 - 数据可视化入门(Matplotlib Seaborn)

&#x1f3af; 今日目标 掌握 Matplotlib 的基本绘图方法&#xff08;折线图、柱状图、饼图&#xff09;掌握 Seaborn 的高级绘图方法&#xff08;分类图、分布图、箱线图&#xff09;熟悉图像美化&#xff08;标题、标签、颜色、风格&#xff09;完成一组学生成绩数据的可视化…...

WebRTC(八):SDP

SDP 概念 SDP 是一种描述多媒体通信会话的文本格式&#xff08;基于 MIME&#xff0c;RFC 4566&#xff09;。本身 不传输数据&#xff0c;仅用于在会话建立阶段传递信息。常与 SIP&#xff08;VoIP&#xff09;、RTSP、WebRTC 等协议配合使用。 用途 描述媒体类型&#xf…...

《哈希表》K倍区间(解题报告)

文章目录 零、题目描述一、算法概述二、算法思路三、代码实现四、算法解释五、复杂度分析 零、题目描述 题目链接&#xff1a;K倍区间 一、算法概述 计算子数组和能被k整除的子数组数量的算法。通过前缀和与哈希表的结合&#xff0c;高效地统计满足条件的子数组。  需要注…...

牛津大学开源视频中的开放世界目标计数!

视频中的开放世界目标计数 GitHub PaPer Niki Amini-Naieni nikianrobots.ox.ac.uk Andrew Zisserman azrobots.ox.ac.uk 视觉几何组&#xff08;VGG&#xff09;&#xff0c;牛津大学&#xff0c;英国 ​ 图 1&#xff1a;视频中的目标计数&#xff1a;给定顶行的视频&#…...

1.2、CAN总线帧格式

1、帧类型 2、帧类型介绍 &#xff08;1&#xff09;数据帧 扩展格式是为了扩展ID&#xff0c;ID号每4位一个字节&#xff08;11位最大ID号为0x7FF&#xff09; &#xff08;2&#xff09;遥控帧 遥控帧由于没有Data&#xff0c;所以DLC可能没有意义&#xff0c;可给任意值&am…...

DeepSeek今天喝什么随机奶茶推荐器

用DeepSeek生成了一个随机奶茶推荐器-今天喝什么&#xff0c;效果非常棒&#xff01;UI界面美观。 提示词prompt如下 用html5帮我生成一个今天喝什么的网页 点击按钮随机生成奶茶品牌等&#xff0c;要包括中国常见的知名的奶茶品牌 如果不满意还可以随机再次生成 ui界面要好看 …...

词编码模型怎么进行训练的,输出输入是什么,标签是什么

词编码模型怎么进行训练的,输出输入是什么,标签是什么 词编码模型的训练本质是通过数据驱动的方式,将离散的文本符号映射为连续的语义向量。 一、训练机制:从符号到向量的映射逻辑 1. 核心目标 将单词/子词(Token)映射为低维向量,使语义相关的词在向量空间中距离更近…...

LSTM、GRU 与 Transformer网络模型参数计算

参数计算公式对比 模型类型参数计算公式关键组成部分LSTM4 (embed_dim hidden_size hidden_size hidden_size)4个门控结构GRU3 (embed_dim hidden_size hidden_size hidden_size)3个门控结构Transformer (Encoder)12 embed_dim 9 embed_dim ff_dim 14 embed_dim…...

nnv开源神经网络验证软件工具

一、软件介绍 文末提供程序和源码下载 用于神经网络验证的 Matlab 工具箱&#xff0c;该工具箱实现了可访问性方法&#xff0c;用于分析自主信息物理系统 &#xff08;CPS&#xff09; 领域中带有神经网络控制器的神经网络和控制系统。 二、相关工具和软件 该工具箱利用神经…...

SQLite3 在嵌入式系统中的应用指南

SQLite3 在嵌入式系统中的应用指南 一、嵌入式系统中 SQLite3 的优势 SQLite3 是嵌入式系统的理想数据库解决方案&#xff0c;具有以下核心优势&#xff1a; 特性嵌入式系统价值典型指标轻量级适合资源受限环境库大小&#xff1a;500-700KB零配置无需数据库管理员开箱即用无…...

原生微信小程序网络请求与上传接口封装实战指南

本文基于微信小程序原生 API&#xff0c;封装 request 和 uploadFile 接口&#xff0c;最终实现统一请求管理、请求拦截、错误处理等能力。 &#x1f4e6; 一、为什么要封装网络请求&#xff1f; 微信小程序提供了 wx.request 和 wx.uploadFile 原生 API&#xff0c;但直接使用…...

电路图识图基础知识-塔式起重机控制电路识图与操作要点(三十五)

引言&#xff1a; 塔式起重机作为建筑施工中不可或缺的大型起重运输机械设备&#xff0c;其控制电路的识图与操作对于确保施工安全和效率至关重要。本文将详细介绍塔式起重机的控制电路识图&#xff0c;帮助操作人员更好地理解和掌握其工作原理。 一、塔式起重机概述 塔式起重…...

基于SpringBoot + Vue 的网上拍卖系统

基于springbootvue的在线拍卖系统| Java | vue | 配万字文档 | springboot001 〔运行环境〕 Java版本&#xff1a;jdk1.8 node版本&#xff1a;13.x python版本&#xff1a;2.7 IDE类型&#xff1a;idea或exlipse 数据库&#xff1a;MySQL&#xff08;5.x或8.x版本都…...

用 EXCEL/WPS 实现聚类分析:赋能智能客服场景的最佳实践

聚类分析作为无监督学习的核心技术&#xff0c;能在客服数据中发现隐藏的用户群体或问题模式。尽管 Excel/WPS 并非专业统计软件&#xff0c;但巧妙利用其内置功能&#xff0c;也能实现基础的聚类分析&#xff0c;为中小型客服团队提供快速洞察。以下介绍具体方法及智能客服场景…...

利用mold加快rust程序构建

我用rust的cargo build命令编译polars-cli时&#xff0c;用时达到14分钟&#xff0c;如下所示。 Finished dev profile [unoptimized debuginfo] target(s) in 14m 19s&#xff0c;通过核对时间戳&#xff0c;发觉其中最后一步生成可执行文件花了6分钟。 于是向DeepSeek请教&a…...

leetcode543-二叉树的直径

leetcode 543 思路 路径长度计算&#xff1a;任意两个节点之间的路径长度&#xff0c;等于它们的最低公共祖先到它们各自的深度之和递归遍历&#xff1a;通过后序遍历&#xff08;左右根&#xff09;计算每个节点的左右子树深度&#xff0c;并更新全局最大直径深度与直径的关…...

(三)yolov5——模型训练

一、准备数据 先准备一个MP4的视频 1.测试一帧 使用opencv来提取每一个视频的帧 先使用以下代码查看一帧的内容&#xff0c;是否符合预期 import cv2 import matplotlib.pyplot as plt# 打开视频文件 video cv2.VideoCapture("111.mp4") # 读取一帧 ret, frame…...

STM32对接霍尔传感器

STM32对接霍尔传感器的技术解析与应用实现,结合测速原理、硬件设计、代码实现及进阶应用,涵盖从基础到实战的全流程指南,可以应用到金属检测等功能。 ⚙️ 一、霍尔传感器基础 工作原理 霍尔传感器基于霍尔效应,当磁铁靠近时输出电平变化(常开型无磁铁时输出高电平,靠近时…...

SpringCloud系列(32)--使用Hystrix进行全局服务降级

前言&#xff1a;在上一节中我们使用Hystrix进行了服务降级&#xff0c;但是要在每个方法上面配置HystrixCommand才能实现服务降级&#xff0c;如果需要进行服务降级的方法多了&#xff0c;HystrixCommand也就得配置很多遍&#xff0c;所以本节内容则是使用Hystrix进行了全局服…...

Origin绘制三Y轴柱状图、点线图、柱状点线图

三Y轴柱状图是一种高级数据可视化形式&#xff0c;它通过三个独立的纵轴在同一个图表中展示不同量纲或量级的数据系列。其主要用于揭示不同量级指标间的关联性&#xff08;例如高销售额是否伴随高利润率&#xff09;。 当数据满足以下条件时&#xff0c;即可绘制三Y轴图&#x…...

通信网络编程3.0——JAVA

主要添加了私聊功能 1服务器类定义与成员变量 public class ChatServer {int port 6666;// 定义服务器端口号为 6666ServerSocket ss;// 定义一个 ServerSocket 对象用于监听客户端连接//List<Socket> clientSockets new ArrayList<>();// 定义一个列表用于存储…...

4-深度学习网络层

深度学习模型 Embedding层 Embedding矩阵是可训练的参数&#xff0c;一般会在模型构建时随机初始化 也可以使用预训练的词向量来做初始化&#xff0c;此时也可以选择不训练Embedding层中的参数 输入的整数序列可以有重复&#xff0c;但取值不能超过Embedding矩阵的列数 核心…...

【LeetCode】用双指针解决移除元素问题、合并两个有序数组求解

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;…...

车载诊断架构协议篇 --- OBDonUDS和ZEVonUDS

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 做到欲望极简&#xff0c;了解自己的真实欲望&#xff0c;不受外在潮流的影响&#xff0c;不盲从&#x…...

医学 Agent:自带医学深度调研 deep research,优化治疗策略+药物参考

医学 Agent&#xff1a;自带医学深度调研deep research&#xff0c;优化治疗策略药物参考 第一版代码输出结果&#xff0c;居然连不上网运行结果梳理 第二版结果测试 第一版代码 医疗顾问AI系统 - 基于Qwen API 的智能医疗助手 最终目标&#xff1a;构建一个能够查询疾病治疗方…...

硬件工程师笔试面试高频考点汇总——(2025版)

目录 1 电子器件部分 1.1 电阻 1.1.1 电阻选型时一般从哪几个方面进行考虑? 1.1.2 上拉下拉电阻的作用 1.1.3 PTC热敏电阻作为电源电路保险丝的工作原理 1.1.4 如果阻抗不匹配&#xff0c;有哪些后果 1.1.5 电阻、电容和电感0402、0603和0805封装的含义 1.1.6 电阻、电…...

春秋云镜【CVE-2017-18349】fastjson wp

知识点 fastjson反序列化 将json转为java对象的过程 漏洞存在版本 Fastjson<1.2.24 漏洞原理 fastjson引入的autotype功能&#xff0c;本来是为了区分同名同元素但是不同类型的对象序列化后内容一致无法还原的问题&#xff0c;但是这一操作允许了json数据中通过type来指定对…...

网络编程:八股文

一.Reactor网络模型 ------------------- | 应用主线程 | -------------------|v ------------------- | Reactor | | (事件分发器) | -------------------|v ------------------- | 事件多路分发器 | <--- epoll/poll/select -----------------…...

设计模式精讲 Day 11:享元模式(Flyweight Pattern)

【设计模式精讲 Day 11】享元模式&#xff08;Flyweight Pattern&#xff09; 文章内容 在软件开发过程中&#xff0c;我们常常需要处理大量相似对象的创建和管理问题。如果这些对象之间存在大量的重复信息&#xff0c;直接创建每一个对象会导致内存占用过高、系统性能下降。享…...

常用终端命令(Linux/macOS/bash 通用)分类速查表

文件与目录操作 命令作用说明pwd显示当前路径ls列出当前目录内容ls -l以列表形式显示文件详细信息ls -a显示所有文件&#xff08;包括隐藏文件&#xff09;cd <目录名>进入指定目录cd ..返回上一级目录cd ~回到用户主目录mkdir <目录名>创建目录mkdir -p a/b/c创建…...

Robyn高性能Web框架系列04:事件、中间件与错误处理

请求-响应过程 应用启动、关闭事件1、启动事件&#xff08;Startup Events&#xff09;2、关闭事件&#xff08;Shutdown Events&#xff09; 中间件1、前置中间件&#xff08;BeforeRequest&#xff09;2、后置中间件&#xff08;AfterRequest&#xff09;3、示例&#xff1a;…...