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

opencv 图像的旋转

图像的旋转

  • 1 单点旋转
  • 2. 图片旋转(cv2.getRotationMatrix2D)
  • 3. 插值方法
    • 3.1 最近邻插值(cv2.INTER_NEAREST)
    • 3.2 双线性插值(cv2.INTER_LINEAR)
    • 3.3 像素区域插值(cv2.INTER_AREA)
    • 3.4 双三次插值(cv2.INTER_CUBIC)
    • 3.5 Lanczos插值(cv2.INTER_LANCZOS4)
    • 3.6 小结
  • 4. 边缘填充方式(cv2.warpAffine的属性borderMode)
    • 4.1 边界复制(BODER_REPLICATE)
      • 4.2 边界反射(BORDER_REFLECT)
    • 4.3 边界反射101(BORDER_REFLECT_101)
    • 4.4 边界常数(BORDER_CONSTANT)
      • 4.5 边界包裹(BORDER_WRAP)

图像旋转是指图像以某一点为旋转中心,将图像中的所有像素点都围绕该点旋转一定的角度,并且旋转后的像素点组成的图像与原图像相同。

1 单点旋转

首先我们以最简单的一个点的旋转为例子,且以最简单的情况举例,令旋转中心为坐标系中心O(0,0),假设有一点 P 0 ( x 0 , y 0 ) P_{0}(x_{0},y_{0}) P0(x0,y0) P 0 P_{0} P0离旋转中心O的距离为r, O P 0 OP_{0} OP0与坐标轴x轴的夹角为 α \alpha α P 0 P_{0} P0绕O顺时针旋转 θ \theta θ角后对应的点为 P ( x , y ) P(x,y) P(x,y),如下图所示:

在这里插入图片描述
单点旋转的原理

2. 图片旋转(cv2.getRotationMatrix2D)

明白了单个点的旋转过程之后,其实图像旋转也很好理解,就是将图像里的每个像素点都带入仿射变换矩阵里,从而得到旋转后的新坐标。在OpenCV中,要得到仿射变换矩阵可以使用cv2.getRotationMatrix2D(),通过这个函数即可直接获取到上面的旋转矩阵,
格式如下:

cv2.RotationMatrix2D(Center,Angle,Scale)

该函数需要接收的参数为:

  • Center:表示旋转的中心点,是一个二维的坐标点(x,y)
  • Angle:表示旋转的角度
  • Scale:表示缩放比例,可以通过该参数调整图像相对于原始图像的大小变化

因此,在本实验中只需要在组件中填好图片要旋转的角度与缩放的比例即可。
在这里插入图片描述
代码如下:

 '''图片的旋转'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle=angle,scale=sacle)img_rotate=cv2.warpAffine(img,m,(w,h))cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述

但是这里会有一个问题:

  • 由于三角函数的值是小数,那么其乘积也会是小数,虽然OpenCV中会对其进行取整操作,但是像素点旋转之后的取整结果也有可能重合,这样就会导致可能会在旋转的过程中丢失一部分原始的像素信息。
  • 并且如果使用了scale参数进行图像的缩放的话,当图像放大时,比如一个10*10的图像放大成20*20,图像由100个像素点变成400个像素点,那么多余的300个像素点是怎么来的?而当图像缩小时,比如一个20*20的图像缩小为10*10的图像,需要丢掉300个像素点,那到底要怎么丢才能保证图像还能是一个正常的图像?
  • 因此我们需要一种方法来帮我们计算旋转后的图像中每一个像素点所对应的像素值,从而保证图像的完整性,这种方法就叫做插值法。

3. 插值方法

在图像处理和计算机图形学中,插值(Interpolation)是一种通过已知数据点之间的推断或估计来获取新数据点的方法。它在图像处理中常用于处理图像的放大、缩小、旋转、变形等操作,以及处理图像中的像素值。

图像插值算法是为了解决图像缩放或者旋转等操作时,由于像素之间的间隔不一致而导致的信息丢失和图像质量下降的问题。当我们对图像进行缩放或旋转等操作时,需要在新的像素位置上计算出对应的像素值,而插值算法的作用就是根据已知的像素值来推测未知位置的像素值。本实验提供了五种常见的插值算法,下面一一介绍。

3.1 最近邻插值(cv2.INTER_NEAREST)

最近邻插值的原理
代码如下:

'''最近邻插值法'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1.5#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_NEAREST)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述

3.2 双线性插值(cv2.INTER_LINEAR)

双线性插值的原理
代码如下:

 '''双线性插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1.5#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_LINEAR)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述
注意:

  • 双线性插值和最近邻插值的区别就,当放大倍数为小数时,最近邻插值(cv2.INTER_NEAREST)是对结果下取整,而双线性插值(cv2.INTER_LINEAR)根据距离哪个像素点近就将取大的权值
  • 在这里插入图片描述

3.3 像素区域插值(cv2.INTER_AREA)

像素区域插值主要分两种情况,缩小图像和放大图像的工作原理并不相同。

当使用像素区域插值方法进行缩小图像时,它就会变成一个均值滤波器(滤波器其实就是一个核,这里只做简单了解,后面实验中会介绍),其工作原理可以理解为对一个区域内(均值滤波器/核)的像素值取平均值。

当使用像素区域插值方法进行放大图像时,如果图像放大的比例是整数倍,那么其工作原理与最近邻插值类似;如果放大的比例不是整数倍,那么就会调用双线性插值进行放大。

其中目标像素点与原图像的像素点的对应公式如下所示:
s r c X = d s t X ∗ s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstXdstWidthsrcWidth

s r c Y = d s t Y ∗ s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstYdstHeightsrcHeight
代码如下:

 '''像素区域插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1.5#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_AREA)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      


像素区域插值(cv2.INTER_AREA)就是最近邻插值和双线性插值的结合

3.4 双三次插值(cv2.INTER_CUBIC)

与双线性插值法相同,该方法也是通过映射,在映射点的邻域内通过加权来得到放大图像中的像素值。不同的是,双三次插值法需要原图像中近邻的16个点来加权。

目标像素点与原图像的像素点的对应公式如下所示:
s r c X = d s t X ∗ s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstXdstWidthsrcWidth

s r c Y = d s t Y ∗ s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstYdstHeightsrcHeight

下面我们举例说明,假设原图像A大小为m*n,缩放后的目标图像B的大小为M*N。其中A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一个像素点(X,Y)的值,必须先找出像素(X,Y)在原图像A中对应的像素(x,y),再根据原图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。

假如下图中的P点就是目标图像B在(X,Y)处根据上述公式计算出的对应于原图像A中的位置,P的坐标位置会出现小数部分,所以我们假设P点的坐标为(x+u,y+v),其中x、y表示整数部分,u、v表示小数部分,那么我们就可以得到其周围的最近的16个像素的位置,我们用a(i,j)(i,j=0,1,2,3)来表示,如下图所示。

在这里插入图片描述

然后给出BiCubic函数:
JYBx-1745050039632)

其中,a一般取-0.5或-0.75。

我们要做的就是将上面的16个点的坐标带入函数中,获取16像素所对应的权重 W ( x ) W(x) W(x)。然而BiCubic函数是一维的,所以我们需要将像素点的行与列分开计算,比如a00这个点,我们需要将x=0带入BiCubic函数中,计算a00点对于P点的x方向的权重,然后将y=0带入BiCubic函数中,计算a00点对于P点的y方向的权重,其他像素点也是这样的计算过程,最终我们就可以得到P所对应的目标图像B在(X,Y)处的像素值为:
B ( X , Y ) = ∑ i = 0 3 ∑ j = 0 3 a i j × W ( i ) × W ( j ) B(X,Y)=\sum_{i=0}^{3}\sum_{j=0}^{3}a_{i j}\times W_{(i)}\times W_{(j)} B(X,Y)=i=03j=03aij×W(i)×W(j)
依此办法我们就可以得到目标图像中所有的像素点的像素值。

代码如下:

'''双三次插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1.5#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_CUBIC)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在这里插入图片描述
双三次插值(cv2.INTER_CUBIC)比双线性插值(cv2.INTER_LINEAR)对图片处理更精细,但是执行效率比较低

3.5 Lanczos插值(cv2.INTER_LANCZOS4)

Lanczos插值方法与双三次插值的思想是一样的,不同的就是其需要的原图像周围的像素点的范围变成了8*8,并且不再使用BiCubic函数来计算权重,而是换了一个公式计算权重。

首先还是目标像素点与原图像的像素点的对应公式如下所示:
s r c X = d s t X ∗ s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstXdstWidthsrcWidth

s r c Y = d s t Y ∗ s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstYdstHeightsrcHeight

下面我们举例说明,假设原图像A大小为m*n,缩放后的目标图像B的大小为M*N。其中A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一个像素点(X,Y)的值,必须先找出像素(X,Y)在原图像A中对应的像素(x,y),再根据原图像A距离像素(x,y)最近的64个像素点作为计算目标图像B(X,Y)处像素值的参数,利用权重函数求出64个像素点的权重,图B像素(x,y)的值就等于64个像素点的加权叠加。

假如下图中的P点就是目标图像B在(X,Y)处根据上述公式计算出的对应于原图像A中的位置,P的坐标位置会出现小数部分,所以我们假设P点的坐标为(x+u,y+v),其中x、y表示整数部分,u、v表示小数部分,那么我们就可以得到其周围的最近的64个像素的位置,我们用a(i,j)(i,j=0,1,2,3,4,5,6,7)来表示,如下图所示。

在这里插入图片描述

然后给出权重公式:
在这里插入图片描述

其中a通常取2或者3,当a=2时,该算法适用于图像缩小。a=3时,该算法适用于图像放大。

与双三次插值一样,这里也需要将像素点分行和列分别带入计算权重值,其他像素点也是这样的计算过程,最终我们就可以得到P所对应的目标图像B在(X,Y)处的像素值为:
S ( x , y ) = ∑ i = [ x ] − a + 1 [ x ] + a ∑ j = [ y ] − a + 1 [ y ] + a s i j L ( x − i ) L ( y − j ) S(x,y)=\sum_{i=[x]-a+1}^{[x]+a}\sum_{j=[y]-a+1}^{[y]+a}s_{i j}L(x-i)L(y-j) S(x,y)=i=[x]a+1[x]+aj=[y]a+1[y]+asijL(xi)L(yj)
其中 [ x ] [x] [x] [ y ] [y] [y]表示对坐标值向下取整,通过该方法就可以计算出新的图像中所有的像素点的像素值。
代码如下:

 '''lanczos'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1.5#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_LANCZOS4)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在这里插入图片描述

3.6 小结

最近邻插值的计算速度最快,但是可能会导致图像出现锯齿状边缘和失真,效果较差。双线性插值的计算速度慢一点,但效果有了大幅度的提高,适用于大多数场景。双三次插值、Lanczos插值的计算速度都很慢,但是效果都很好。

在OpenCV中,关于插值方法默认选择的都是双线性插值,且一般情况下双线性插值已经能满足大部分需求。

4. 边缘填充方式(cv2.warpAffine的属性borderMode)

在这里插入图片描述

可以看到,左图在逆时针旋转45度之后原图的四个顶点在右图中已经看不到了,同时,右图的四个顶点区域其实是什么都没有的,因此我们需要对空出来的区域进行一个填充。右图就是对空出来的区域进行了像素值为(0,0,0)的填充,也就是黑色像素值的填充。除此之外,后续的一些图像处理方式也会用到边缘填充,这里介绍五个常用的边缘填充方法。

4.1 边界复制(BODER_REPLICATE)

边界复制会将边界处的像素值进行复制,然后作为边界填充的像素值,如下图所示,可以看到四周的像素值都一样。
在这里插入图片描述
代码如下:

 '''边界复制'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REPLICATE)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在这里插入图片描述

4.2 边界反射(BORDER_REFLECT)

如下图所示,会根据原图的边缘进行反射。
在这里插入图片描述

代码如下:

 '''边界反射'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)    

在这里插入图片描述
边界反射是将原图沿着原图的边界镜像复制填充整个边框

4.3 边界反射101(BORDER_REFLECT_101)

与边界反射不同的是,不再反射边缘的像素点,如下图所示。
在这里插入图片描述
代码如下:

 '''边界反射_101'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT_101)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述
边界反射101是将原图以原图的边界为轴镜像复制填充整个边框

4.4 边界常数(BORDER_CONSTANT)

当选择边界常数时,还要指定常数值是多少,默认的填充常数值为0,如下图所示。

img2=cv2.warpAffine(img,M,(shape[1],shape[0]),flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT,borderValue=100)


代码如下:

'''边界常数'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)#边界常数(borderMode=cv2.BORDER_CONSTANT)的边界值(borderVlue)为0则是黑色,如果就是一个值的话是将bgr这三个值都赋值为这个值img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_CONSTANT,borderValue=(0,0,255))cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述
边界常数(borderMode=cv2.BORDER_CONSTANT)的边界值(borderVlue)为0则是黑色,如果就是一个值的话是将bgr这三个值都赋值为这个值

4.5 边界包裹(BORDER_WRAP)

如下图所示。
在这里插入图片描述
代码如下:

'''边界包裹'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出图片的高宽和颜色h,w,c=img.shape# 给出一个旋转角度angle=45# 给出缩放倍数sacle=1#给出缩放后的图像的窗口大小frame=(2*w,2*h)# 以图片的中心作为旋转中心的仿射变换矩阵m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_WRAP)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在这里插入图片描述
边界包裹(cv2.BORDER_WRAP)的含义就是将图片平铺填充窗口

相关文章:

opencv 图像的旋转

图像的旋转 1 单点旋转2. 图片旋转(cv2.getRotationMatrix2D)3. 插值方法3.1 最近邻插值(cv2.INTER_NEAREST)3.2 双线性插值(cv2.INTER_LINEAR)3.3 像素区域插值(cv2.INTER_AREA)3.4 双三次插值(cv2.INTER_CUBIC&#…...

P3916 图的遍历

P3916 图的遍历 题目来源-洛谷 题意 有向图中,找出每个节点能访问到的最大的节点 思路 每个节点的最大节点,不是最长距离,如果是每个节点都用dfs去找最大值,显然1e6*1e6 超时了,只能60分从第一个节点开始遍历&…...

Vue3 + Three.js 场景编辑器开发实践

文章目录 前言项目背景与意义项目技术栈在线演示核心功能实现1. 智能化场景管理2. 专业级模型处理3. 可视化材质与照明4. 相机与渲染引擎5. 场景操作 项目优势开发目标1. 几何模型和模型导入,场景新建按钮增加2. 提供场景内容的可视化编辑功能3. 渲染器场景&#xf…...

Vue3 本地打包启动白屏解决思路!! !

“为什么我访问 http://127.0.0.1:5501/index.html 白屏,删了 index.html 再访问 / 就又活过来了?” —— 你的项目与 SPA 路由的“宫斗大戏” 一、问题复现 场景 本地通过 VSCode Live Server(或其他静态服务器)启动了打包后的 V…...

Ubuntu 安装 Docker 教程(官方推荐方式)

✅ 步骤 1:卸载旧版本(如果有) for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done---### ✅ 步骤 2:更新 APT 索引并安装依赖项bash sudo a…...

WPF 点击按钮,显示隐藏另一个控件

<Button Content"显示隐藏" Click"operationDetails_Click" /> private void operationDetails_Click(object sender, RoutedEventArgs e) { 另一个控件的Name.Visibility 另一个控件的Name.Visibility Visibility.Visible ? Visibility.Col…...

RBAC的使用

1、简述RBAC的作用及工作流程 Rbac基于角色访问控制&#xff0c;用于管理用户对集群资源的访问权限&#xff0c;通过定义角色和绑定规则&#xff0c;将用户与权限进行关联&#xff0c;作用&#xff1a;权限精细化管理&#xff0c;操作便捷与统一管理&#xff0c;动态调整权限。…...

QML中的3D功能--模型导入与修改

在Qt 3D中导入和修改3D模型是开发3D应用程序的基础。以下是详细的流程和技术方案: 一、模型导入基础 1. 支持的文件格式 Qt 3D支持多种3D模型格式: OBJ (Wavefront) FBX (Autodesk) DAE (Collada) GLTF/GLB (推荐格式) STL (3D打印格式) 2. 基本导入方法 qml import Qt3…...

树莓派超全系列教程文档--(33)树莓派启动选项

树莓派启动选项 启动选项start_file &#xff0c;fixup_filecmdlinekernelarm_64bitramfsfileramfsaddrinitramfsauto_initramfsdisable_poe_fandisable_splashenable_uartforce_eeprom_reados_prefixotg_mode &#xff08;仅限Raspberry Pi 4&#xff09;overlay_prefix配置属…...

dotnet core webapi 实现 异常处理中间件

目录 第一步&#xff1a;创建异常处理中间件类&#xff08;自定义响应格式&#xff09; 第二步&#xff1a;在 Program.cs 中使用中间件 三、效果 第一步&#xff1a;创建异常处理中间件类&#xff08;自定义响应格式&#xff09; public static class ExceptionMiddleware…...

实现Azure Function安全地请求企业内部API返回数据

需要编写一个Function在Azure云上运行&#xff0c;它需要访问企业内部的API获取JSON格式的数据&#xff0c;企业有网关和防火墙&#xff0c;API有公司的okta身份认证&#xff0c;通过公司的域账号来授权访问&#xff0c;现在需要创建一个专用的域账号&#xff0c;让Function访问…...

实现Azure Databricks安全地请求企业内部API返回数据

需要编写一个Databricks在Azure云上运行&#xff0c;它需要访问企业内部的API获取JSON格式的数据&#xff0c;企业有网关和防火墙&#xff0c;API有公司的okta身份认证&#xff0c;通过公司的域账号来授权访问&#xff0c;现在需要创建一个专用的域账号&#xff0c;让Databrick…...

结合建筑业务讲述TOGAF标准处理哪种架构

TOGAF标准处理哪种架构 内容介绍业务架构业务策略&#xff0c;治理&#xff0c;组织和关键业务流程数据架构组织的逻辑和物理数据资产以及数据管理资源的结构应用架构待部署的各个应用程序&#xff0c;它们之间的交互以及与组织核心业务流程的关系的蓝图技术架构支持业务&#…...

深度学习--卷积神经网络CNN原理

文章目录 一、CNN图像原理1、了解CNN如何处理图像 二、CNN图像识别1、画面不变性2、主要表现1&#xff09;平移不变性2&#xff09;尺度不变性3&#xff09;旋转不变性 3、传统神经网络1&#xff09;数据预处理2&#xff09;特征提取3&#xff09;搭建神经网络模型4&#xff09…...

PostgreSQL 常用客户端工具

PostgreSQL 常用客户端工具 PostgreSQL 拥有丰富的客户端工具生态系统&#xff0c;以下是各类常用工具的详细分类和介绍&#xff1a; 一 图形化客户端工具 1.1 跨平台工具 工具名称特点适用场景许可证pgAdmin官方出品&#xff0c;功能全面开发/运维PostgreSQLDBeaver支持多…...

PostgreSQL数据库yum方式安装详解

PostgreSQL数据库yum方式安装 1. 基础环境配置2. 前期安装准备3. 软件安装3.1 YUM方式安装&#xff08;PG 13&#xff09;3.1.1 安装rpm仓库3.1.2 安装软件包PG133.1.3 初始化数据库3.1.4 启动数据库3.1.5 开机自启动3.1.6 编辑环境变量 4. 安装后配置 1. 基础环境配置 2. 前期…...

浅析vue2和vue3的区别

以下是 Vue 2 和 Vue 3 的主要区别: 一、核心特性 1. 响应式机制 Vue 2: 基于 Object.defineProperty 实现响应式。无法检测对象属性的新增和删除,需要使用 Vue.set 或 $set。Vue 3: 使用 Proxy 替代 Object.defineProperty。能够直接检测对象属性的新增和删除,无需额外方…...

【Linux我做主】make和makefile自动化构建

make和makefile自动化构建 make和makefile自动化构建github地址前言背景介绍为什么需要make和makefile&#xff1f; make和makefile解析什么是make和makefile依赖关系和依赖方法核心语法结构简单演示编译清理 多阶段编译示例 make时执行的顺序场景1&#xff1a;clean目标在前(特…...

spring boot应用部署IIS

Windows IIS 部署 Spring Boot 应用详细指南 本文档提供了在 Windows Server 上使用 IIS 部署 Spring Boot 应用的完整步骤和最佳实践。 目录 概述前期准备Spring Boot 应用准备安装配置必要组件配置 IIS 站点配置反向代理配置 Windows 服务配置应用自启动HTTPS 配置日志配置…...

Linux系统之部署TestNet资产管理系统

Linux系统之部署TestNet资产管理系统 一、TestNet 介绍1.1 TestNet简介1.2 主要特点1.3 主要使用场景 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、部署TestNet系统4.1 下载T…...

@EnableAsync+@Async源码学习笔记之六

接上文&#xff0c;我们本文分析 AsyncExecutionAspectSupport 的源码&#xff1a; package org.springframework.aop.interceptor;import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFu…...

SQL系列:常用函数

1、【MySQL】合并字段函数&#xff08;列转行&#xff09; 它可以将两个字段中的数据合并到一个字段中。 1&#xff09;CONCAT函数 CONCAT函数可以将多个字段中的数据合并到一个字段中。它的语法格式如下&#xff1a; SELECT CONCAT(字段1,字段2,...字段N) FROM 表名;SELEC…...

Git 中修改某个特定的commit提交内容

在 Git 中修改某个特定的提交&#xff08;commit&#xff09;通常需要使用 交互式变基&#xff08;Interactive Rebase&#xff09; 或 修改提交&#xff08;Commit Amend&#xff09;。以下是不同场景下的具体操作步骤&#xff1a; 一、修改最近的提交&#xff08;最新提交&am…...

FHS --- linux目录结构(部分目录解释)

根目录&#xff08;/&#xff09; 的意义和内容 &#xff1a; 根目录是整个系统最重要的一个目录&#xff0c;因为不但所有的目录都是由根目录衍生出来的&#xff0c;同时根目录也与开机/还原/系统修复等动作有关 。 由于系统开机时需要特定的开机软件、核心档案、开机所需程序…...

不带无线网卡的Linux开发板上网方法

I.MX6ULL通过网线上网 设置WLAN共享修改开发板的IP 在使用I.MX6ULL-MINI开发板学习Linux的时候&#xff0c;有时需要更新或者下载一些资源包&#xff0c;但是开发板本身是不带无线网卡或者WIFI芯片的&#xff0c;尝试使用网口连接笔记本&#xff0c;笔记本通过无线网卡连接WIFI…...

图书管理系统C语言

图书管理系统C语言代码示例。 该系统可以实现图书信息&#xff08;包含图书编号、书名、作者、出版社、价格、库存数量&#xff09;的录入、显示、查询、修改、删除等功能&#xff0c;还具备一定的错误处理和输入验证。 #include <stdio.h> #include <stdlib.h> …...

关于大型语言模型的“生物学”

我知道我们已经聊过很多次&#xff0c;关于LLM是怎么运作的&#xff0c;它们的影响力&#xff0c;还有它们的使用场景。但尽管现在有那么多讲LLM的文章&#xff0c;它们本质上还是个黑箱。 但我们真正要问自己的问题是&#xff0c;为什么理解这些系统的内部结构很重要&#xf…...

图像预处理-图像边缘检测(流程)

一.高斯滤波 因为图像边缘检测就是把像素值有差异的地方提取出来&#xff0c;所以噪声会有很大影响&#xff0c;因此需要对图像进行平滑处理&#xff0c;高斯滤波是流程中常用的方法。 二.计算图像的梯度与方向 过程中通常使用sobel算子进行梯度计算&#xff0c;在OpenCV中&am…...

解锁思想道德修养的奥秘:用思维导图开启智慧之旅

在我们的成长过程中&#xff0c;思想道德修养如同基石&#xff0c;奠定了我们为人处世、面对生活挑战的基本态度和准则。而如何高效地梳理和掌握思想道德修养的丰富内容呢&#xff1f;思维导图这一强大工具为我们提供了独特视角和便捷途径。 思想道德修养的关键板块 道德理论…...

swagger的简介及使用方法

Swagger 是一个用于描述、生成、文档化和测试 RESTful API 的开源工具集。它可以自动生成 API 文档&#xff0c;帮助开发者理解和使用 API。Swagger 由 Swagger.io 提供&#xff0c;并已经发展成了一套广泛应用于 API 设计和文档的标准。 Swagger 项目的历史可以追溯到 2010 年…...

解决Ubuntu图形化界面操作适配问题

1 缘起 使用Ubuntu GNOME图形化系统作为开发机&#xff0c; 遇到与Windows操作不一致的地方&#xff0c;比如PyCharm、IntelliJ时无法正确代码跳转&#xff0c; 如CtrlAltLeft&#xff0c;CtrlAltRight无法正常在代码级别跳转&#xff0c;只能在文件级别跳转。 基于这个开端&a…...

End-to-End从混沌到秩序:基于LLM的Pipeline将非结构化数据转化为知识图谱

摘要:本文介绍了一种将非结构化数据转换为知识图谱的端到端方法。通过使用大型语言模型(LLM)和一系列数据处理技术,我们能够从原始文本中自动提取结构化的知识。这一过程包括文本分块、LLM 提示设计、三元组提取、归一化与去重,最终利用 NetworkX 和 ipycytoscape 构建并可…...

使用Ingress发布应用程序

使用Ingress发布应用程序 文章目录 使用Ingress发布应用程序[toc]一、什么是Ingress二、定义Ingress三、什么是Ingress控制器四、部署nginx Ingress控制器1.了解nginx Ingress控制器的部署方式2.安装nginx Ingress控制器3.本地实际测试 五、使用Ingress对外发布应用程序1.使用D…...

llama-factory微调报错:

报错信息 [INFO] [utils.py:789:see_memory_usage] CPU Virtual Memory: used 81.51 GB, percent 64.9% W0419 10:14:27.573000 108354 site-packages/torch/distributed/elastic/multiprocessing/api.py:897] Sending process 108373 closing signal SIGTERM W0419 10:14:27…...

【LLaMAFactory】LoRa + 魔搭 微调大模型实战

前言 环境准备 之前是在colab上玩&#xff0c;这次在国内的环境上玩玩。 魔搭&#xff1a;https://www.modelscope.cn/ 现在注册&#xff0c;有100小时的GPU算力使用。注册好了之后&#xff1a; 魔搭社区 这里使用qwen2.5-7B-Instruct模型&#xff0c;这里后缀Instruct是指…...

【愚公系列】《Python网络爬虫从入门到精通》054-Scrapy 文件下载

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…...

db中查询关于null的sql该怎么写

正确示例 # 等于null select * from 表名 where 字段名 is NULL; # 不等于null select * from 表名 where 字段名 is not NULL;若需要同时判断字段不等于某个值且不为null select * from users where age ! 30 and age is not null; select * from users where age ! 30 or a…...

React 文章列表

自定义hook 在src/hooks文件夹下封装 useChannel.js // 获取频道列表的逻辑 import { useEffect , useState } from "react" import { getChannelAPI } from "/apis/article"function useChannel(){// 获取频道的逻辑 const [channelList,setChannelList…...

中间件--ClickHouse-12--案例-1-日志分析和监控

1、案例背景 一家互联网公司需要实时分析其服务器日志、应用日志和用户行为日志&#xff0c;以快速发现潜在问题并优化系统性能。 2、需求分析 目标&#xff1a;实时分析日志数据&#xff0c;快速发现问题并优化系统性能。数据来源&#xff1a; 服务器日志&#xff1a;如 Ng…...

QML中的3D功能--自定义着色器开发

在 Qt 3D 中使用自定义着色器可以实现高度定制化的渲染效果。以下是完整的自定义着色器开发方案。 一、基础着色器创建 1. 创建自定义材质 qml import Qt3D.Core 2.15 import Qt3D.Render 2.15 import Qt3D.Extras 2.15Entity {components: [Transform { translation: Qt.v…...

如何防止接口被刷

目录 &#x1f6e1;️ 一、常见的防刷策略分类 &#x1f527; 二、技术实现细节 ✅ 1. 基于 IP 限流 ✅ 2. 给接口加验证码 ✅ 3. 使用 Token 限制接口访问权限 ✅ 4. 给接口加冷却时间&#xff08;验证码类经典&#xff09; ✅ 5. 使用滑动窗口限流算法&#xff08;更精…...

18、TimeDiff论文笔记

TimeDiff **1. 背景与动机****2. 扩散模型基础****3. TimeDiff 模型****3.1 前向扩散过程****3.2 后向去噪过程** 4、TimeDiff&#xff08;架构&#xff09;原理训练推理其他关键点解释 DDPM&#xff08;相关数学&#xff09;1、正态分布2、条件概率1. **与多个条件相关**&…...

docker底层原理

一句话&#xff0c;dockerfile里面的一行指令&#xff0c;就是一个layer层 docker底层原理 在机器上安装docker服务器端的程序&#xff0c;就会在机器上自动创建以下目录&#xff0c;默认安装路径是/var/lib/ docker服务器端的工作目录的作用如下&#xff0c;镜像的每一层的元数…...

YOLO拓展-NMS算法

1.概述 NMS&#xff08;non maximum suppression&#xff09;即非极大值抑制&#xff0c;其本质就是搜索局部极大值&#xff0c;抑制非极大值元素&#xff0c;可以理解为局部最大搜索。 这里不讨论通用的NMS算法(参考论文《Efficient Non-Maximum Suppression》对1维和2维数据…...

Docker Swarm 容器与普通 Docker 容器的网卡差异

问题背景 在 Docker Swarm 网络空间启动的容器有两张网卡&#xff08;eth0 和 eth1&#xff09;&#xff0c;而普通 Docker 容器只有一张网卡&#xff08;eth0&#xff09;。以下通过分析 ip addr show 和 ip link show 的输出&#xff0c;解释原因。 命令输出解析 Docker S…...

【Linux】线程ID、线程管理、与线程互斥

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f310; C 语言 上篇文章&#xff1a; 【Linux】线程&#xff1a;从原理到实战&#xff0c;全面掌握多线程编程&#xff01;-CSDN博客 下…...

服务器简介(含硬件外观接口介绍)

服务器&#xff08;Server&#xff09;是指提供资源、服务、数据或应用程序的计算机系统或设备。它通常比普通的个人计算机更强大、更可靠&#xff0c;能够长时间无间断运行&#xff0c;支持多个用户或客户端的请求。简单来说&#xff0c;服务器就是专门用来存储、管理和提供数…...

自动驾驶---决策规划之导航增强端到端

1 背景 自动驾驶算法通常包括几个子任务&#xff0c;包括3D物体检测、地图分割、运动预测、3D占用预测和规划。近年来&#xff0c;端到端方法将多个独立任务整合到多任务学习中&#xff0c;优化整个系统&#xff0c;包括中间表示&#xff0c;以实现最终的规划任务。随着端到端技…...

Datawhale AI春训营 世界科学智能大赛--合成生物赛道:蛋白质固有无序区域预测 小白经验总结

一、报名大赛 二、跑通baseline 在魔塔社区创建实例&#xff0c;根据教程完成速通第一个分数~ Datawhale-学用 AI,从此开始 三、优化实例&#xff08;这里是我的学习优化过程&#xff09; 1.先将官方给的的模型训练实例了解一遍&#xff08;敲一敲代码&#xff09; 训练模…...

基于Java(Struts2 + Hibernate + Spring)+MySQL实现的(Web)在线预约系统

基于Struts2 Hibernate Spring的在线预约系统 1.引言 1.1编写目的 针对医院在线预约挂号系统&#xff0c;提供详细的设计说明&#xff0c;包括系统的需求、功能模块、界面设计、设计方案等&#xff0c;以辅助开发人员顺利进行系统的开发并让项目相关者可以对这个系统进行分…...