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

Python----计算机视觉处理(Opencv:霍夫变换)

一、霍夫变换

        霍夫变换是图像处理中的一种技术,主要用于检测图像中的直线、圆或其他形状。其基本思想就是将图像空间中的点映射到参数空间中,通过在参数空间中寻找累计最大值来实现对特定形状的检测。

二、 霍夫直线变换

        那么对于一个二值化后的图形来说,其中的每一个目标像素点(这里假设目标像素点为白色像素点)都 对应了霍夫空间的一条直线,当霍夫空间中有两条直线相交时,就代表了直角坐标系中某两个点可以构 成一条直线。而当霍夫空间中有很多条线相交于一点时,说明直角坐标系中有很多点能构成一条直线, 也就意味着这些点共线,因此我们就可以通过检测霍夫空间中有最多直线相交的交点来找到直角坐标系 中的直线。 

        根据上图,霍夫空间在极坐标系下,一点可以产生一条三角函数曲线,而多条这样的曲线可能会相交于 同一点。因此,我们可以通过设定一个阈值,来检测霍夫空间中的三角函数曲线相交的次数。如果一个 交点的三角函数曲线相交次数超过阈值,那么这个交点所代表的直线就可能是我们寻找的目标直线。

具体步骤为:

        1. 建立二维累加数组(也成为累加器),并将其全部初始化为0。

        2. 把图像中边缘检测所得到的点的坐标带入直线的极坐标方程中,求得每个点所对应的关于 和 的方 程。

        3. 不断的将 的值带入方程中,求得对应的\rho值,再累加器中对应的位置上进行加1。

        4. 重复步骤3直到所有的点的方程都带入过所有的\theta值为止。

        5. 处理完毕后,找到累加器中的最大值所对应的\rho\theta,即是我们要找的直线方程所对应的\rho\theta

三、统计概率霍夫直线变换

        霍夫直线变换(Probabilistic Hough Transform),是一种改进的霍夫变换,它在获取到直线之后,会检测原图中在该直线上的点,并获取到 两侧的端点坐标,然后通过两个点的坐标来计算该直线的长度,通过直线长度与最短长度阈值的比较来 决定该直线要不要被保留。

四、霍夫圆变换

        我们只需要将图像中检测到的边缘点的坐标带入到参数空间中,去生成对应的圆锥,然后求取圆锥的交 点即可。但是这种传统的方法有一个很大的缺陷,那就是参数空间的数据从二维变成了三维,数据量变 大了很多,计算量也会大很多,所以在其基础上做了改进,就有了霍夫梯度法。

        霍夫梯度法利用了边缘点的梯度做了一次降维的操作,将数据从三维重新降到了二维,方便我们去计 算。它主要分为两个步骤,首先是先去寻找圆心,然后再去寻找半径。

        由于我们的检测是基于边缘检测所得到的点来进行的,而进行边缘检测时就能得到边缘点的梯度方向。 对于圆这种特殊的形状来说,其边缘点的梯度方向会指向圆心, 所以我们可以利用边缘点的梯度方向做 一条经过该边缘点的直线。如果将所有边缘点都这么操作的话,最后这些直线相交次数最多的地方就是 圆心所在的地方。这个操作仅仅只是考虑了圆心的坐标所在,并没有考虑半径,所以还是一次二维空间 下的操作。

        找到了圆心所在之后,计算所有的边缘点与圆心的距离,得到的结果相同的次数最多的结果就是半径。 只需要不断的去带入不同的半径的值,就可以得到最终的圆的参数,及圆心和半径。

        这里要注意的是,圆的半径并不是无限大的,由于我们是要检测一张图片中的圆的存在,假如图片的大 小是一个正方形的存在,那么圆的直径不可能超过正方形的长度;如果图片的大小是一个矩形,那么圆 的直径不可能超过矩形最短边的长度。也就是说图片中的圆最大也就是一个基于图片大小的内切圆,所 以第二步寻找半径的过程中不会让半径进行无限的增大。 

其具体步骤为:

        1. 首先去寻找圆心所在,所以构建一个关于(a,b)的二维累加器,并初始化为0。

        2. 计算所有边缘点的梯度角的正切值。

        3. 对于一个边缘点,将其正切值带入a关于b的表达式中,得到表达式的结果后,不断带入a的值并计 算出每一个对应的b值。

        4. 将得到的每一对(a,b)在累加器中对应的位置进行加一,进行统计。

        5. 重复步骤3、步骤4,直到所有的边缘点处理完毕。

        6. 找到累加器中值最大的区域所对应的a和b的值,那么此时的(a,b)就是我们要找的圆的圆心坐 标。

        7. 得到圆心之后,计算所有的边缘点与圆心之间的距离,找到距离出现次数最高的结果,该结果就是 以(a,b)为圆心的圆的半径。

五、霍夫变换

5.1、霍夫直线变换

导入模块

import cv2
import numpy as np

输入图像

img=cv2.imread('img_1.png')

灰度化

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
边缘检测
img_canny=cv2.Canny(img_gray,30,70)

霍夫直线变换

lines=cv2.HoughLines(img_canny,0.8,np.pi/180,120)

创建模板

img_res=np.zeros(img_shape,dtype=np.uint8)
在模板上绘图
for i in lines:rho,theta=i[0]cos_theta=np.cos(theta)sin_theta=np.sin(theta)x1,x2=0,img_shape[1]y1=int((rho-x1*cos_theta)/sin_theta)y2 = int((rho - x2 * cos_theta) / sin_theta)cv2.line(img_res,(x1,y1),(x2,y2),color=(0,0,255))

输出图像

cv2.imshow('img_res',img_res)
cv2.waitKey(0)

完整代码

import cv2  
import numpy as np  # 读取输入图像  
img = cv2.imread('img_1.png')  
img_shape = img.shape  # 获取图像形状(高度, 宽度, 通道数)  # 将图像转换为灰度图  
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 使用 Canny 算子检测边缘,参数为低阈值和高阈值  
img_canny = cv2.Canny(img_gray, 30, 70)  # 使用 Hough 变换检测线条  
# 参数:输入边缘图像,ρ的精度(0.8 像素),θ的精度(以弧度为单位),阈值(最小投票数)  
lines = cv2.HoughLines(img_canny, 0.8, np.pi/180, 120)  # 创建一个空图像,用于存放检测到的线条  
img_res = np.zeros(img_shape, dtype=np.uint8)  # 遍历检测到的线条  
for i in lines:  rho, theta = i[0]  # 获取线条的极坐标表示(ρ 和 θ)  cos_theta = np.cos(theta)  # 计算 cos(θ)  sin_theta = np.sin(theta)  # 计算 sin(θ)  # 设定线条的起始点和结束点  x1, x2 = 0, img_shape[1]  # 线条的起点 x1 = 0,终点 x2 = 图像宽度  # 计算对应的 y1 和 y2 值  y1 = int((rho - x1 * cos_theta) / sin_theta)  # 计算起点 y 坐标  y2 = int((rho - x2 * cos_theta) / sin_theta)  # 计算终点 y 坐标  # 在结果图像上绘制检测到的线条  cv2.line(img_res, (x1, y1), (x2, y2), color=(0, 0, 255))  # 线条颜色为红色  # 显示结果图像  
cv2.imshow('img_res', img_res)  
cv2.waitKey(0)  # 等待按键操作  
cv2.destroyAllWindows()  # 关闭所有 OpenCV 窗口  

5.2、统计概率霍夫直线变换

 

导入模块

import cv2
import numpy as np

输入图像

img=cv2.imread('img_1.png')

灰度化

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
边缘检测
img_canny=cv2.Canny(img_gray,30,70)

统计概率霍夫直线变换

lines=cv2.HoughLinesP(img_canny,0.8,np.pi/180,90,minLineLength=50,maxLineGap=10)

创建模板

img_res=np.zeros(img_shape,dtype=np.uint8)
在模板上绘图
for i in lines:x1,y1,x2,y2=i[0]cv2.line(img_res,(x1,y1),(x2,y2),color=(0,0,255))

输出图像

cv2.imshow('img_res',img_res)
cv2.waitKey(0)

完整代码

import cv2  
import numpy as np  # 读取输入图像  
img = cv2.imread('img_1.png')  # 从文件加载图像  
img_shape = img.shape  # 获取图像的形状(高度, 宽度, 通道数)  # 将图像转换为灰度图  
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 使用 Canny 算子检测边缘,参数为低阈值和高阈值  
img_canny = cv2.Canny(img_gray, 30, 70)  # 使用 Hough 变换提取线段(HoughLinesP),该方法更适用于检测短线段  
# 参数:输入边缘图像,ρ的精度(0.8 像素),θ的精度(以弧度为单位),  
#       阈值(最小投票数),最小线段长度(50 像素),最大线段间隙(10 像素)  
lines = cv2.HoughLinesP(img_canny, 0.8, np.pi/180, 90, minLineLength=50, maxLineGap=10)  # 创建一个空图像,用于存放检测到的线段  
img_res = np.zeros(img_shape, dtype=np.uint8)  # 初始化带有 zeros 的相同形状的图像  # 遍历检测到的线段  
for i in lines:  x1, y1, x2, y2 = i[0]  # 获取每条线段的起始点 (x1, y1) 和结束点 (x2, y2)  # 在结果图像上绘制检测到的线段  cv2.line(img_res, (x1, y1), (x2, y2), color=(0, 0, 255))  # 线条颜色为红色  # 显示结果图像  
cv2.imshow('img_res', img_res)  # 在窗口中显示结果图像  
cv2.waitKey(0)  # 等待用户按键,任何键按下后关闭窗口  
cv2.destroyAllWindows()  # 关闭所有 OpenCV 创建的窗口  

5.3、霍夫圆变换

  

导入模块

import cv2
import numpy as np

输入图像

img=cv2.imread('img_1.png')

灰度化

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
边缘检测
img_canny=cv2.Canny(img_gray,30,70)

霍夫圆变换

circels=cv2.HoughCircles(img_gray,cv2.HOUGH_GRADIENT_ALT,1.5,20,param1=30,param2=0.9)
circels=np.uint(np.around(circels))

创建模板

img_res=np.zeros(img_shape,dtype=np.uint8)
在模板上绘图
for i in circels:x,y,circel=i[0]cv2.circle(img_res,(x,y),circel,(0,0,255),thickness=2)

输出图像

cv2.imshow('img_res',img_res)
cv2.waitKey(0)

完整代码

import cv2  
import numpy as np  # 读取输入图像  
img = cv2.imread('img_1.png')  # 从文件中加载图像  
img_shape = img.shape  # 获取图像的形状(高度, 宽度, 通道数)  # 将图像转换为灰度图  
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 使用 Hough 圆变换检测圆  
# 参数:输入图像,检测方法(HOUGH_GRADIENT_ALT),比例(1.5),最小距离(20),  
#       参数1(边缘检测的高阈值,param1),参数2(中心检测的阈值,param2)  
circels = cv2.HoughCircles(img_gray, cv2.HOUGH_GRADIENT_ALT, 1.5, 20, param1=30, param2=0.9)  # 如果检测到圆,进行转化和四舍五入以获得整数坐标  
if circels is not None:  # 确保检测到了圆  circels = np.uint16(np.around(circels))  # 转换为无符号整数并四舍五入  # 创建一个空图像,用于存放检测到的圆  img_res = np.zeros(img_shape, dtype=np.uint8)  # 初始化带有 zeros 的相同形状的图像  # 遍历检测到的圆  for i in circels:  x, y, circel = i[0]  # 获取每个圆的中心坐标 (x, y) 和半径 circel  # 在结果图像上绘制检测到的圆  cv2.circle(img_res, (x, y), circel, (0, 0, 255), thickness=2)  # 颜色为红色,厚度为2  # 显示结果图像  
cv2.imshow('img_res', img_res)  # 在窗口中显示结果图像  
cv2.waitKey(0)  # 等待用户按键,任何键按下后关闭窗口  
cv2.destroyAllWindows()  # 关闭所有 OpenCV 创建的窗口  

六、库函数 

6.1、Canny()

使用 Canny 算法查找图像中的边缘 [48] 。

该函数在输入图像中查找边缘,并使用 Canny 算法在输出映射边缘中标记它们。threshold1 和 threshold2 之间的最小值用于 Edge 链接。最大值用于查找强边缘的初始分段。查看 http://en.wikipedia.org/wiki/Canny_edge_detector

cv.Canny(	image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]	) ->	edges
cv.Canny(	dx, dy, threshold1, threshold2[, edges[, L2gradient]]	) ->	edges
方法描述
image8 位输入图像。
edges输出边缘映射;单通道 8 位图像,其大小与 图像 相同。
threshold1磁滞过程的第一个阈值。
threshold2滞后程序的第二个阈值。
apertureSize孔径大小。
L2gradient

6.2、HoughLines()

使用标准 Hough 变换在二进制图像中查找线条。

该函数实现用于线检测的标准或标准多尺度 Hough 变换算法。有关霍夫变换的良好解释,请参见 http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm。

cv.HoughLines(	image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta[, use_edgeval]]]]]]	) ->	lines
方法描述
image8 位、单通道二进制源图像。该函数可以修改图像。
lines线的输出向量。每条线都由 2 或 3 个元素向量表示,或 ,其中 是距坐标原点(图像左上角)的距离,是以弧度 ( ) 为单位的线旋转角度,是累加器的值。
rho累加器的距离分辨率(以像素为单位)。
theta累加器的角度分辨率(以弧度为单位)。
threshold二值化参数
srn对于多尺度 Hough 变换,它是距离分辨率 rho 的除数。粗略累加器距离分辨率为 rho,精确累加器分辨率为 rho/srn。如果 srn=0 和 stn=0,则使用经典霍夫变换。否则,这两个参数都应该为正。
stn对于多尺度 Hough 变换,它是距离分辨率 theta 的除数。
min_theta对于标准和多比例霍夫变换,检查线条的最小角度。必须介于 0 和 max_theta 之间。
max_theta对于标准和多尺度霍夫变换,角度的上限。必须介于 min_theta 和 CV_PI 之间。蓄能器中的实际最大角度可能略小于 max_theta,具体取决于参数 min_theta 和 theta。
use_edgeval如果要使用加权 Hough 变换,则为 True。

6.3、line()

绘制连接两点的线段。

函数 line 在图像中的 pt1 和 pt2 点之间绘制线段。该线被图像边界剪切。对于具有整数坐标的非抗锯齿线,使用 8 连通或 4 连通 Bresenham 算法。粗线绘制有圆角结尾。抗锯齿线是使用高斯过滤绘制的。

cv.line(	img, pt1, pt2, color[, thickness[, lineType[, shift]]]	) ->	img
方法描述
img图像
pt1线段的第一个点。
pt2线段的第二个点。
color线条颜色。
thickness线条粗细。
lineType线路的类型。请参见 LineTypes
shift点坐标中的小数位数

6.4、HoughLinesP()

使用概率 Hough 变换在二进制图像中查找线段。

该函数实现了用于线检测的概率 Hough 变换算法

cv.HoughLinesP(	image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]	) ->	lines
方法描述
image8 位、单通道二进制源图像。该函数可以修改图像。
lines线的输出向量。每条线都由 2 或 3 个元素向量表示,或 ,其中 是距坐标原点(图像左上角)的距离,是以弧度 ( ) 为单位的线旋转角度,是累加器的值。
rho累加器的距离分辨率(以像素为单位)。
theta累加器的角度分辨率(以弧度为单位)。
threshold二值化参数
minLineLength最小行长。短于此值的线段将被拒绝。
maxLineGap同一条线上的点之间允许的最大间隙以链接它们。

 

6.5、HoughCircles()

使用 Hough 变换在灰度图像中查找圆圈。

该函数使用修改 Hough 变换在灰度图像中查找圆圈。

cv.HoughCircles(	image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]	) ->	circles

注意

通常,该函数可以很好地检测圆心。但是,它可能无法找到正确的半径。如果您知道,可以通过指定半径范围( minRadius 和 maxRadius )来协助该函数。或者,在HOUGH_GRADIENT方法的情况下,您可以将 maxRadius 设置为负数,以便仅返回中心而不进行半径搜索,并使用其他过程找到正确的半径。

方法描述
image8 位、单通道、灰度输入图像
circles找到的圆的输出向量
method检测方法,请参阅 HoughModes。可用的方法包括 HOUGH_GRADIENT 和 HOUGH_GRADIENT_ALT。
dp累加器分辨率与图像分辨率的反比。例如, 如果 dp=1 ,则累加器的分辨率与输入图像相同。如果 dp=2 ,则累加器的宽度和高度只有一半。对于 HOUGH_GRADIENT_ALT,建议的值为 dp=1.5,除非需要检测一些非常小的圆圈。
minDist检测到的圆的中心之间的最小距离。如果参数太小,则除了 true 圆圈外,还可能会错误地检测到多个相邻圆圈。如果它太大,可能会错过一些圆圈。
param1第一个特定于方法的参数。在 HOUGH_GRADIENT 和 HOUGH_GRADIENT_ALT 的情况下,它是传递给 Canny 边缘检测器的两个阈值中的较高阈值(较低的阈值小两倍)。请注意,HOUGH_GRADIENT_ALT 使用 Scharr 算法来计算图像导数,因此阈值通常应更高,例如 300 或正常曝光和对比度的图像。
param2第二个特定于方法的参数。如果是 HOUGH_GRADIENT,则它是检测阶段圆心的累加器阈值。它越小,检测到的假圆圈就越多。与较大的 accumulator 值相对应的圆圈将首先返回。在 HOUGH_GRADIENT_ALT 算法的情况下,这是圆 “perfectness” 度量。它越接近 1,算法选择的形状越好。在大多数情况下,0.9 应该没问题。如果您想更好地检测小圆圈,您可以将其降低到 0.85、0.8 甚至更低。但随后也要尝试限制搜索范围 [minRadius, maxRadius] 以避免出现许多假圆圈。
minRadius最小圆半径。
maxRadius最大圆半径。如果 <= 0,则使用最大图像尺寸。如果< 0,则 HOUGH_GRADIENT 返回中心,而不查找半径。HOUGH_GRADIENT_ALT始终计算圆半径。

6.6、circle()

绘制一个圆。

函数 cv::circle 绘制一个具有给定圆心和半径的简单圆或实心圆。

cv.circle(	img, center, radius, color[, thickness[, lineType[, shift]]]	) ->	img
方法描述
img绘制圆的图像。
center圆心。
radius圆的半径。
color圆形颜色。
thickness圆轮廓的粗细(如果为正)。负值(如 FILLED)表示要绘制实心圆。
lineType圆边界的类型。请参阅线型
shiftcenter 坐标和 radius 值中的小数位数。

相关文章:

Python----计算机视觉处理(Opencv:霍夫变换)

一、霍夫变换 霍夫变换是图像处理中的一种技术&#xff0c;主要用于检测图像中的直线、圆或其他形状。其基本思想就是将图像空间中的点映射到参数空间中&#xff0c;通过在参数空间中寻找累计最大值来实现对特定形状的检测。 二、 霍夫直线变换 那么对于一个二值化后的图形来说…...

多语言生成语言模型的少样本学习

摘要 大规模生成语言模型&#xff0c;如GPT-3&#xff0c;是极具竞争力的少样本学习模型。尽管这些模型能够共同表示多种语言&#xff0c;但其训练数据以英语为主&#xff0c;这可能限制了它们的跨语言泛化能力。在本研究中&#xff0c;我们在一个涵盖多种语言的语料库上训练了…...

k8s存储介绍(二)Secret

Kubernetes&#xff08;K8s&#xff09;提供了一种安全的方式来存储和管理敏感信息&#xff0c;如密码、OAuth 令牌和 SSH 密钥&#xff0c;这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中&#xff0c;从而提高安全性和可管理性。 1. Secret 的…...

代理IP与AI的碰撞:网络安全新防线解码

目录 一、代理IP&#xff1a;网络世界的“隐形斗篷” 二、AI加持&#xff1a;代理IP的“智能升级包” 三、协同作战&#xff1a;五大核心应用场景 场景1&#xff1a;智能风控系统 场景2&#xff1a;跨境电商竞品分析 场景3&#xff1a;智能汽车安全测试 场景4&#xff1a…...

QT开发(4)--各种方式实现HelloWorld

目录 1. 编辑框实现 2. 按钮实现 前面已经写过通过标签实现的了&#xff0c;所以这里就不写了&#xff0c;通过这两个例子&#xff0c;其他的也是同理 1. 编辑框实现 编辑框分为单行编辑框&#xff08;QLineEdit&#xff09;双行编辑框&#xff08;QTextEdit&#xff09;&am…...

UniApp 生命周期钩子的应用场景

UniApp 生命周期钩子的应用场景 应用生命周期钩子的应用场景 onLaunch 应用初始化&#xff1a;在应用第一次启动时进行全局数据的初始化&#xff0c;比如设置全局配置信息、初始化用户登录状态等。例如&#xff0c;在应用启动时检查本地存储中是否有用户的登录信息&#xff0…...

macOS 安装 Miniconda

macOS 安装 Miniconda 1. Quickstart install instructions2. 执行3. shell 上初始化 conda4. 关闭 终端登录用户名前的 base参考 1. Quickstart install instructions mkdir -p ~/miniconda3 curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o…...

可发1区的超级创新思路(python\matlab实现):基于周期注意力机制的TCN-Informer时间序列预测模型

首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 一、应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、电机故障检测等等 二、模型整体介绍(本文以光伏功率预测为例) 1.1 核心创新点 本模型通过三阶段…...

Nordic Semiconductor 芯片(如 nRF52/nRF53 系列)的 VSCode 开发环境的步骤

目录 概述 1. 安装必要工具链 2. 安装 VSCode 扩展 3. 配置环境变量 4. 克隆/配置 Nordic SDK 5. 创建 VSCode 项目 6. 配置调试 7. 构建与烧录 8. 其他工具 总结 概述 本文主要介绍Nordic Semiconductor 芯片&#xff08;如 nRF52/nRF53 系列&#xff09;的 VSCode…...

Flutter 输入组件 Radio 详解

1. 引言 在 Flutter 中&#xff0c;Radio 是用于单选的按钮组件&#xff0c;适用于需要用户在多个选项中选择一个的场景&#xff0c;如表单、设置选项等。Radio 通过 value 和 groupValue 进行状态管理&#xff0c;并结合 onChanged 监听选中状态的变化。本文将介绍 Radio 的基…...

3.23学习总结

完成了组合Ⅲ&#xff0c;和电话号码的字母组合两道算法题&#xff0c;都是和回溯有关的&#xff0c;很类似。 学习了static的关键字和继承有关知识...

Spring Boot整合Activiti工作流详解

1. 概述 Spring Boot与Activiti的整合可以大大简化工作流应用的开发。Spring Boot提供了自动配置和依赖管理,而Activiti则提供了强大的工作流功能。通过整合,我们可以快速构建基于工作流的业务系统。 本文将详细介绍Spring Boot与Activiti的整合方法,并通过一个请假流程的…...

C# System.Text.Encoding 使用详解

总目录 前言 在C#编程中&#xff0c;处理字符串和字节数组之间的转换是一个常见的任务。System.Text.Encoding类及其派生类提供了丰富的功能&#xff0c;帮助开发者实现不同字符编码之间的转换。本文将详细讲解System.Text.Encoding类的使用方法&#xff0c;包括常用编码的介绍…...

力扣刷题-热题100题-第23题(c++、python)

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/reverse-linked-list/solutions/551596/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 记录前一个指针&#xff0c;当前指针&am…...

机器学习-基于KNN算法手动实现kd树

目录 一、概括 二、KD树的构建流程 1.循环选轴 2.选择分裂点 三、kd树的查询 1.输入我们要搜索的点 2.递归向下遍历&#xff1a; 3.记录最近点 4.回溯父节点&#xff1a; 四、KD树的优化与变种&#xff1a; 五、KD树代码&#xff1a; 上一章我们将了机器学习-手搓KN…...

Unity Shader 的编程流程和结构

Unity Shader 的编程流程和结构 Unity Shader 的编程主要由以下三个核心部分组成&#xff1a;Properties&#xff08;属性&#xff09;、SubShader&#xff08;子着色器&#xff09; 和 Fallback&#xff08;回退&#xff09;。下面是它们的具体作用和结构&#xff1a; 1. Pr…...

vue3 项目的最新eslint9 + prettier 配置

注意&#xff1a;eslint目前升级到9版本了 在 ESLint v9 中&#xff0c;配置文件已经从 .eslintrc 迁移到了 eslint.config.js 配置的方式和之前的方式不太一样了&#xff01;&#xff01;&#xff01;&#xff01; 详见自己的语雀文档&#xff1a;5、新版eslint9prettier 配…...

SAP GUI Script for C# SAP脚本开发快速指南与默认主题问题

SAP GUI Script for C# 快速指南 SAP 脚本的快速使用与设置. 解决使用SAP脚本执行后,默认打开的SAP是经典主题的问题 1. 解决默认主题问题 如果您使用的是SAP GUI 740&#xff0c;并遇到无法打开对话框的问题&#xff0c;请先将主题设置为经典主题&#xff08;Classic Theme…...

JAVA泛型的作用

‌1. 类型安全&#xff08;Type Safety&#xff09;‌ 在泛型出现之前&#xff0c;集合类&#xff08;如 ArrayList、HashMap&#xff09;只能存储 Object 类型元素&#xff0c;导致以下问题&#xff1a; ‌问题‌&#xff1a;从集合中取出元素时&#xff0c;需手动强制类型转…...

Git Flow 分支管理策略

优势 清晰的分支结构&#xff1a;每个分支都有明确的用途&#xff0c;便于团队协作。 稳定的 master 分支&#xff1a;生产环境代码始终稳定。 灵活的发布管理&#xff1a;通过发布分支和热修复分支&#xff0c;可以灵活管理版本发布和紧急修复。 主要分支 master 分支 代表…...

FFmpeg + ‌Qt‌ 简单视频播放器代码

一个基于 ‌FFmpeg 4.x‌ 和 ‌Qt‌ 的简单视频播放器代码示例&#xff0c;实现视频解码和渲染到 Qt 窗口的功能。 1&#xff09;ffmpeg库界面&#xff0c;视频解码支持软解和硬解方式。 2&#xff09;QImage/QPixmap显示视频图片。 ‌1. Qt 项目配置&#xff08;.pro 文件&…...

Unity跨平台构建快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、发布应用程序1. 修改发布必备设置1.1 打开设置面板1.2 修改公司名、游戏项目名、版本号和默认图标1.3 修改 Package Name 和 Minimum API Level 2. 发布应用程序2.1 配置 Build Settings2.2 选择发布选项2.3 构…...

【嵌入式学习2】内存管理

## C语言编译过程 预处理&#xff1a;宏定义展开、头文件展开、条件编译&#xff0c;这里并不会检查语法&#xff0c;将#include #define这些头文件内容插入到源码中 gcc -E main.c -o main.i 编译&#xff1a;检查语法&#xff0c;将预处理后文件编译生成汇编文件&#xff…...

密码学(Public-Key Cryptography and Discrete Logarithms)

Public-Key Cryptography and Discrete Logarithms Discrete Logarithm 核心概念&#xff1a;离散对数是密码学中一个重要的数学问题&#xff0c;特别是在有限域和循环群中。它基于指数运算在某些群中是单向函数这一特性。也就是说&#xff0c;给定一个群 G G G和一个生成元 …...

TDengine又新增一可视化工具 Perspective

概述 Perspective 是一款开源且强大的数据可视化库&#xff0c;由 Prospective.co 开发&#xff0c;运用 WebAssembly 和 Web Workers 技术&#xff0c;在 Web 应用中实现交互式实时数据分析&#xff0c;能在浏览器端提供高性能可视化能力。借助它&#xff0c;开发者可构建实时…...

【Linux文件IO】Linux中标准IO的API的描述和基本用法

Linux中标准IO的API的描述和基本用法 一、标准IO相关API1、文件的打开和关闭示例代码&#xff1a; 2、文件的读写示例代码&#xff1a;用标准IO&#xff08;fread、fwrite&#xff09;实现文件拷贝(任何文件均可拷贝) 3、文件偏移设置示例代码&#xff1a; 4、fgets fputs fget…...

深度学习篇---PaddleDetectionPaddleOCR

文章目录 前言1.代码2.代码介绍2.1 **导入模块**2.2 **配置区域**2.3 ExpressInfoProcessor类2.4 **主程序**&#xff1a; 3.使用说明3.1环境准备3.2模型准备3.3数据库初始化3.4串口配置3.5信息提取优化3.6注意事项 前言 本文简单介绍了PaddleDetection和PaddleOCR相结合的示例…...

Ant Design Vue Select 选择器 全选 功能

Vue.js的组件库Ant Design Vue Select 选择器没有全选功能&#xff0c;如下图所示&#xff1a; 在项目中&#xff0c;我们自己实现了全选和清空功能&#xff0c;如下所示&#xff1a; 代码如下所示&#xff1a; <!--* 参数配置 - 风力发电 - 曲线图 * 猴王软件学院 - 大强 …...

系统与网络安全------网络应用基础(1)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 TCP/IP协议及配置 概述 TCP/IP协议族 计算机之间进行通信时必须共同遵循的一种通信规定 最广泛使用的通信协议的集合 包括大量Internet应用中的标准协议 支持跨网络架构、跨操作系统平台的数据通信 主机…...

ZIP_STORED和ZIP_LZMA没有compresslevel参数!

在使用py的zipfile库进行压缩的时候&#xff0c;有这么一个函数&#xff1a; def write(self, filename, arcnameNone,compress_typeNone, compresslevelNone): 一般我们在压缩文件进去的时候都是用这个函数的&#xff1b; 对于compresslevel这个函数&#xff0c;它是用来指…...