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

day27图像处理OpenCV

文章目录

  • 一、图像预处理
    • 1 图像翻转(图像镜像旋转)
    • 2 图像仿射变换
      • 2.1 图像旋转
      • 2.2 图像平移
      • 2.3 图像缩放
      • 2.4 图像剪切
    • 3 插值方法
      • 3.1 最近邻插值
      • 3.2 双线性插值(常用)
      • 3.3 像素区域插值--一般缩小使用
      • 3.4 双三次插值
      • 3.5 Lanczos插值

一、图像预处理

1 图像翻转(图像镜像旋转)

在OpenCV中,图片的镜像旋转是以图像的中心为原点进行镜像翻转的。

  • cv2.flip(img,flipcode)

  • 参数

    • img: 要翻转的图像
    • flipcode: 指定翻转类型的标志
      • flipcode=0: 垂直翻转,图片像素点沿x轴往下翻转
      • flipcode=1: 水平翻转,图片像素点沿y轴往左翻转
      • flipcode=-1: 水平垂直翻转,水平翻转和垂直翻转的结合

2 图像仿射变换

​ 仿射变换(Affine Transformation)是一种线性变换,保持了点之间的相对距离不变。

  • 仿射变换的基本性质

    • 保持直线
    • 保持平行
    • 比例不变性
    • 不保持角度和长度
  • 常见的仿射变换类型

    • 旋转:绕着某个点或轴旋转一定角度。
    • 平移:仅改变物体的位置,不改变其形状和大小。
    • 缩放:改变物体的大小。
    • 剪切:使物体发生倾斜变形。
  • 仿射变换的基本原理

    • 线性变换

    • 二维空间中,图像点坐标为(x,y),仿射变换的目标是将这些点映射到新的位置 (x’, y’)。

    • 为了实现这种映射,通常会使用一个矩阵乘法的形式:

      (类似于y=kx+b)

在这里插入图片描述

  • a,b,c,d是线性变换部分的系数,控制旋转、缩放和剪切。

  • t_x,t_y 是平移部分的系数,控制图像在平面上的移动。

    • 输入点的坐标被扩展为齐次坐标形式[x,y,1],以便能够同时处理线性变换和平移
      在这里插入图片描述
  • cv2.warpAffine()函数

    • 仿射变换函数

      cv2.warpAffine(img,M,dsize)
      
      • img:输入图像。

      • M:2x3的变换矩阵,类型为np.float32。下面介绍如何产生

      • dsize:输出图像的尺寸,形式为(width,height)

2.1 图像旋转

旋转图像可以将图像绕着某个点旋转一定的角度。

cv2.getRotationMatrix2D()函数

  • 获取旋转矩阵

    M = cv2.getRotationMatrix2D(center,angle,scale)
    
    • center:旋转中心点的坐标,格式为(x,y)
    • angle:旋转角度,单位为度,正值表示逆时针旋转负值表示顺时针旋转。
    • scale:缩放比例,若设为1,则不缩放。
    • 返回值M,2x3的旋转矩阵。
  • 示例:

import cv2 as cv
import numpy as np
# 读取图片
cat = cv.imread("./imgs/cat1.png")
h, w, _ = cat.shape
center = (w // 2, h // 2)  # 获取中心点
angle = 45  # 旋转角度
scale = 0.6  # 缩放
# 获取旋转矩阵
M = cv.getRotationMatrix2D(center, angle, scale)
# 旋转图片
cat2 = cv.warpAffine(cat, M, (w, h))
cv.imshow("cat", cat)
cv.imshow("cat2", cat2)
cv.waitKey(0)
cv.destroyAllWindows()

2.2 图像平移

移操作可以将图像中的每个点沿着某个方向移动一定的距离。

  • 假设我们有一个点 P ( x , y ) P(x,y) P(x,y),希望将其沿x轴方向平移 t x t_x tx*个单位,沿y轴方向平移 t y t_y ty个单位到新的位置 P ′ ( x ′ , y ′ ) P′(x′,y′) P(x,y),那么平移公式如下:

    x ′ = x + t x x′=x+tx x=x+tx

    y ′ = y + t y y′=y+ty y=y+ty

    在矩阵形式下,该变换可以表示为:

    在这里插入图片描述

    这里的 t x t_x tx t y t_y ty分别代表在x轴和y轴上的平移量

  • 示例:自己手动生成M矩阵

# 读取图片
cat = cv.imread("./imgs/cat1.png")
h, w, _ = cat.shape# 获取平移矩阵---50是x轴平移像素点,60是y轴平移像素点
M = np.float32([[1, 0, 50], [0, 1, 60]])
# 平移后的图片
cat2 = cv.warpAffine(cat, M, (w, h))

2.3 图像缩放

缩放操作可以改变图片的大小。

  • 假设要把图像的宽高分别缩放为0.5和0.8,那么对应的缩放因子sx=0.5,sy=0.8。

  • P ( x , y ) P(x,y) P(x,y)对应到新的位置 P ′ ( x ′ , y ′ ) P'(x',y') P(x,y),缩放公式为:

    x ′ = s x ∗ x x′=s_x*x x=sxx

    y ′ = s y ∗ y y′=s_y*y y=syy

    在矩阵形式下,该变换可以表示为:

    在这里插入图片描述

    相较于图像旋转中只能等比例的缩放,图像缩放更加灵活,可以在指定方向上进行缩放。

sx和sy分别表示在x轴和y轴方向上的缩放因子。

  • 示例:自己手动生成M矩阵
# 读取图片
cat = cv.imread("./imgs/cat1.png")
h, w, _ = cat.shape
sx = 0.5
sy = 0.6
# 获取缩放矩阵---sx是行的缩放系数,sy是列的缩放系数
M = np.float32([[sx, 0, 0], [0, sy, 0]])
# 缩放后的图片---w,h长,宽
cat2 = cv.warpAffine(cat, M, (w, h))

2.4 图像剪切

剪切操作可以改变图形的形状,以便其在某个方向上倾斜,它将对象的形状改变为斜边平行四边形,而不改变其面积

  • 想象我们手上有一张矩形纸片,如果你固定纸片的一边,并沿着另一边施加一个平行于该边的力,这张纸片就会变形为一个平行四边形。这就是剪切变换的一个直观解释。

  • 对于二维空间中的点 P ( x , y ) P(x,y) P(x,y),对他进行剪切变换:

    沿x轴剪切 x ′ = x + s h y ∗ y x'=x+sh_y*y x=x+shyy y ′ = y y'=y y=y

    沿y轴剪切 x ′ = x x'=x x=x y ′ = s h x ∗ x + y y'=sh_x*x+y y=shxx+y

  • 当需要同时沿两个方向进行剪切时, x ′ = x + s h y ∗ y x'=x+sh_y*y x=x+shyy y ′ = s h x ∗ x + y y'=sh_x*x+y y=shxx+y

  • 在矩阵形式下,该变换可以表示为:

    在这里插入图片描述

  • 来一个图理解一下:

    在这里插入图片描述

shy和shx分别对应沿x轴和y轴方向上的剪切因子。

可以理解为,x不变,y偏移

  • 示例:自己手动生成M矩阵
  • shy*y决定竖直方向的偏移量,shx*x决定水平方向的偏移量
  • 图片最右下角发生的拉扯,其他点的变化是为了保持长和宽不变
import cv2 as cv
import numpy as np
# 读取图片
cat = cv.imread("./imgs/cat1.png")
h, w, _ = cat.shape
shy = 0.5
shx = 0.6
# 获取平移矩阵---shy影响竖直方向的偏移量,shx影响水平方向的偏移量
M = np.float32([[1, shy, 0], [shx, 1, 0]])
# 缩放后的图片---w,h长,宽
cat2 = cv.warpAffine(cat, M, (w, h))

3 插值方法

在图像处理中常用于处理图像的放大、缩小、旋转、变形等操作,以及处理图像中的像素值。

当我们对图像进行缩放或旋转等操作时,需要在新的像素位置上计算出对应的像素值,而插值算法的作用就是根据已知的像素值来推测未知位置的像素值。

3.1 最近邻插值

多处理整数,遇到小数要取整。

  • 在获得变化后图像的方法中添加参数flags=cv2.INTER_NEAREST
new_img1=cv.warpAffine(img,M,(w,h),flags=cv.INTER_NEAREST)

变大后的图像点取原图像的哪个坐标点:计算公式

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 Width}{d s t Width}} 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 cY=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

  • dstX:目标图像中某点的x坐标,
  • dstY:目标图像中某点的 y y y坐标,
  • srcWidth:原图的宽度,
  • dstWidth:目标图像的宽度;
  • srcHeight:原图的高度,
  • dstHeight:目标图像的高度。
  • 而srcX和srcY:目标图像中的某点对应的原图中的点的x和y的坐标。

示例:

一张图的第一行像素点的值分别为: 10 10 20 30 40 放大一倍后 新图像的第一行的第3个像素点的值是多少?

  • 待求新点坐标:(2,0)

  • 带公式求原点坐标

    • s r c x = 2 ∗ ( 5 10 ) = 1 s r c x=2*({\frac{5}{10}})=1 srcx=2(105)=1
    • s r c y = 0 ∗ ( 5 10 ) = 0 s r c y=0*({\frac{5}{10}})=0 srcy=0(105)=0
  • 取点(1,0)的像素值10

3.2 双线性插值(常用)

处理小数坐标

  • 在获得变化后图像的方法中添加参数flags=CV2.INTER_LINEAR

原理: 4乘4的图像 变成6乘6的图像 那么目标图像的(3,3)点的像素是原图中(1.8333,1.8333)的像素颜色,但是坐标必须是整数 它周围有四个像素点 该取谁呢? 按照到各自的距离比例 来分配颜色值

  • 示例:

比如我们根据上述公式计算出了新图像中的某点所对应的原图像的点P,其周围的点分别为Q12、Q22、Q11、Q21, 要插值的P点不在其周围点的连线上,这时候就需要用到双线性插值了。首先延申P点得到P和Q11、Q21的交点R1与P和Q12、Q22的交点R2,如下图所示:
在这里插入图片描述

然后根据Q11、Q21得到R1的插值,根据Q12、Q22得到R2的插值,然后根据R1、R2得到P的插值即可,这就是双线性插值。以下是计算过程:

首先计算R1和R2的插值:
f ( R 1 ) ≈ x 2 − x x 2 − x 1 f ( Q 11 ) + x − x 1 x 2 − x 1 f ( Q 21 ) f(R_{1})\approx\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{11})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{21}) f(R1)x2x1x2xf(Q11)+x2x1xx1f(Q21)

f ( R 2 ) ≈ x 2 − x x 2 − x 1 f ( Q 12 ) + x − x 1 x 2 − x 1 f ( Q 22 ) f(R_{2})\approx\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{12})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{22}) f(R2)x2x1x2xf(Q12)+x2x1xx1f(Q22)

然后根据R1和R2计算P的插值:

f ( P ) ≈ y 2 − y y 2 − y 1 f ( R 1 ) + y − y 1 y 2 − y 1 f ( R 2 ) f(P)\approx{\frac{y_{2}-y}{y_{2}-y_{1}}}f(R_{1})+{\frac{y-y_{1}}{y_{2}-y_{1}}}f(R_{2}) f(P)y2y1y2yf(R1)+y2y1yy1f(R2)

这样就得到了P点的插值。注意此处如果先在y方向插值、再在x方向插值,其结果与按照上述顺序双线性插值的结果是一样的。

  • 两个问题:
  • 坐标原点的取值不同,会导致结果不同
    • 原点位置的坐标,一般是直接相同
    • 远离原点的位置,总会进行插值计算
  • 中心位置的像素容易偏离
    • 如下图,变化后的坐标(2,2)对应原坐标(1.2,1.2)
    • 计算的像素会偏离原中心(1,1)

在这里插入图片描述

  • 解决方法:

因此,在OpenCV中,为了解决这两个问题,将公式**(计算新图点对应的原图点)**进行了优化,如下所示:
s r c X = ( d s t X + 0.5 ) ∗ s r c W i d t h d s t W i d t h − 0.5 s r c X=(d s t X+0.5)*{\frac{s r c W i d t h}{d s t W i d t h}}-0.5 srcX=(dstX+0.5)dstWidthsrcWidth0.5

s r c Y = ( d s t Y + 0.5 ) ∗ s r c H e i g h t d s t H e i g h t − 0.5 s r c Y=(d s t Y+0.5)\ast{\frac{s r c H e i g h t}{d s t H e i g h t}}-0.5 srcY=(dstY+0.5)dstHeightsrcHeight0.5

使用该公式计算出原图中的对应坐标后再进行插值计算,就不会出现上面的情况了。

3.3 像素区域插值–一般缩小使用

  • 在获得变化后图像的方法中添加参数flags=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

3.4 双三次插值

  • cv2.INTER_CUBIC
    

双三次插值法需要原图像中近邻的16个点来加权,也就是4x4的网格。

目标像素点与原图像的像素点的对应公式如下所示:
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个像素点的加权叠加。

BiCubic基函数也就是双三次插值的权重函数,它决定了如何根据距离对周围像素进行加权平均。

假如下图中的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函数:

在这里插入图片描述

a一般取-0.5或-0.75,用于控制插值函数的形状。

d代表的是目标像素点与某个像素点之间的相对距离,d_h、d_w

我们要做的就是将上面的16个点相较于p点的位置距离算出来,获取16像素所对应的权重W(d)。然而BiCubic函数是一维的,所以我们需要将像素点的行与列分开计算,比如a00这个点,我们需要将d_x带入BiCubic函数中,计算a00点对于P点的x方向的权重,然后将d_y带入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)
依此办法我们就可以得到目标图像中所有的像素点的像素值。

刚刚我们说拿到了目标点的坐标为 (x+u,y+v) ,其中 x、y 表示整数部分,u、v表示小数部分。那么我们取坐标的整数部分作为参考点,也就是(x,y),小数部分表示目标像素相对于参考点的偏移量。

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]表示对坐标值向下取整,通过该方法就可以计算出新的图像中所有的像素点的像素值。

相关文章:

day27图像处理OpenCV

文章目录 一、图像预处理1 图像翻转(图像镜像旋转)2 图像仿射变换2.1 图像旋转2.2 图像平移2.3 图像缩放2.4 图像剪切 3 插值方法3.1 最近邻插值3.2 双线性插值(常用)3.3 像素区域插值--一般缩小使用3.4 双三次插值3.5 Lanczos插值 一、图像预处理 1 图像翻转(图像镜像旋转) …...

iOS开发--接入ADMob广告失败

接入ADMob的第三方广告,初始化时提示错误如下: state Not Ready;No such adapter in the application 查了各种官方文档,发现接入过程正确,查了Chatgpt和DeepSeek,它们各种分析,分析结果如下: …...

PyTorch进阶学习笔记[长期更新]

第一章 PyTorch简介和安装 PyTorch是一个很强大的深度学习库,在学术中使用占比很大。 我这里是Mac系统的安装,相比起教程中的win/linux安装感觉还是简单不少(之前就已经安好啦),有需要指导的小伙伴可以评论。 第二章…...

vue3 ts 自定义指令 app.directive

在 Vue 3 中,app.directive 是一个全局 API,用于注册或获取全局自定义指令。以下是关于 app.directive 的详细说明和使用方法 app.directive 用于定义全局指令,这些指令可以用于直接操作 DOM 元素。自定义指令在 Vue 3 中非常强大&#xff0…...

【漫话机器学习系列】199.过拟合 vs 欠拟合(Overfit vs Underfit)

机器学习核心问题:过拟合 vs 欠拟合 图示作者:Chris Albon 1. 什么是拟合(Fit)? 拟合(Fit)是指模型对数据的学习效果。 理想目标: 在训练集上效果好 在测试集上效果也好 不复杂、…...

从0到1使用C++操作MSXML

1. 引言 MSXML(Microsoft XML Core Services)是微软提供的一套用于处理XML的COM组件库,广泛应用于Windows平台的XML解析、验证、转换等操作。本文将详细介绍如何从零开始,在C中使用MSXML解析和操作XML文件,包含完整的…...

【中间件】nginx反向代理实操

一、说明 nginx用于做反向代理,其目标是将浏览器中的请求进行转发,应用场景如下: 说明: 1、用户在浏览器中发送请求 2、nginx监听到浏览器中的请求时,将该请求转发到网关 3、网关再将请求转发至对应服务 二、具体操作…...

C语言中冒泡排序和快速排序的区别

冒泡排序和快速排序都是常见的排序算法,但它们在原理、效率和应用场景等方面存在显著区别。以下是两者的详细对比: 一、算法原理 1. 冒泡排序 原理:通过重复遍历数组,比较相邻元素的大小,并在必要时交换它们的位置。…...

进程基本介绍

进程是操作系统的重要内容,都是需要了解和学习的,那么今天我们就来好好看看. 进程基本介绍 1、Linux中,每个执行的程序都称为一个进程,每一个进程都分配一个ID号(pid,进程号). 2.每个进程都可以以两种方式存在的,前台与后台,所谓前台进程就是用户目前的屏幕上可以进行操作的,…...

通过平台大数据智能引擎及工具,构建设备管理、运行工况监测、故障诊断等应用模型的智慧快消开源了

智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。 基于多年的深度…...

不同数据库的注入报错信息

不同数据库在报错注入时返回的报错信息具有显著差异,了解这些差异可以帮助快速判断数据库类型并构造针对性的注入攻击语句。以下是主流数据库的典型报错模式及对比: ​ 目录 ​​ 1. MySQL​​ ​​2. Microsoft SQL Server​​ ​​3. Oracle​​ …...

tcpdump`是一个非常强大的命令行工具,用于在网络上捕获并分析数据包

通过 tcpdump,你可以抓取网络流量,诊断网络问题,或分析通信协议的细节。下面是如何在 Linux 上使用 tcpdump 进行抓包的详细步骤。 1. 安装 tcpdump 在大多数 Linux 发行版中,tcpdump 是默认安装的。如果没有安装,可…...

【漏洞复现】Vite 任意文件读取漏洞 CVE-2025-30208/CVE-2025-31125/CVE-2025-31486/CVE-2025-32395

Vite是什么,和Next.js有什么区别? 我上一篇文章刚介绍了Next.js漏洞的复现: 【漏洞复现】Next.js中间件权限绕过漏洞 CVE-2025-29927_next.js 中间件权限绕过漏洞-CSDN博客 Vite 和 Next.js 是两个不同类型的前端工具,它们各自…...

Odrive源码分析(六) 相关控制变量传递

本文记录下odrive源代码中相关控制模块之间变量的传递,这对理解odrive源代码至关重要。 通过前面文字的分析,odrive有两条数据链路,一条是通过中断进行实时的控制,另外一条是OS相关的操作,主要分析下中断内部的相关变量…...

ARM架构FFmpeg极致优化交叉编译指南

ARM架构FFmpeg极致优化交叉编译指南 一、工具链科学配置 使用最新的ARM官方工具链(Linaro或ARM GNU Toolchain) 确保工具链支持目标平台特定指令集(如NEON, VFP等) 设置正确的–sysroot和–prefix参数 1. 工具链选择原则 # 32位ARM (推荐) wget https://developer.arm.com/…...

zk源码—7.ZAB协议和数据存储一

大纲 1.两阶段提交Two-Phase Commit(2PC) 2.三阶段提交Three-Phase Commit(3PC) 3.ZAB协议算法 4.ZAB协议与Paxos算法 5.zk的数据存储原理之内存数据 6.zk的数据存储原理之事务日志 7.zk的数据存储原理之数据快照 8.zk的数据存储原理之数据初始化和数据同步流程 1.两阶…...

2025蓝桥杯C++A组省赛 题解

昨天打完蓝桥杯本来想写个 p y t h o n python python A A A 组的题解,结果被队友截胡了。今天上课把 C A CA CA 组的题看了,感觉挺简单的,所以来水一篇题解。 这场 B B B 是一个爆搜, C C C 利用取余的性质比较好写&#…...

用哪个机器学习模型 依靠极少量即时静态数据来训练ai预测足球赛的结果?

目录 一、模型推荐 1.集成树模型(XGBoost/CatBoost) 2.逻辑回归(Logistic Regression) 3.贝叶斯概率模型(Naive Bayes或贝叶斯网络) 4.支持向量机(SVM) 二、模型排除 三、训练…...

讲解贪心算法

贪心算法是一种常用的算法思想,其在解决问题时每一步都做出在当前状态下看起来最优的选择,从而希望最终能够获得全局最优解。C作为一种流行的编程语言,可以很好地应用于贪心算法的实现。下面我们来讲一篇关于C贪心算法的文章。 目录 贪心算法…...

0基础 | 电动汽车的“电源翻译官” | DC/DC转换器 | 电源系统三

你有没有想过,电动汽车里那么多五花八门的电子设备,比如车灯、仪表盘、摄像头,甚至连控制马达的“大脑”(ECU),是怎么用上电的?今天就来聊聊电动车里一个默默工作的“小功臣”——DC/DC转换器&a…...

zynq7020 u-boot 速通

zynq u-boot 速通 简介 上回最小系统已经跑起来,证明串口和 ddr 正确配置.现在我们需要正确配置 网口, qspi, emmc. 网口:通过 tftp 下载 dtb,image,rootfs 在线调试.qspi:固化 boot.bin 到 qspi flash,这样 qspi 启动就可以直接运行 u-boot.emmc:存放 ubuntu_base 跟文件系统…...

C++学习之路,从0到精通的征途:string类的模拟实现

目录 一.string类的成员变量与成员函数 二.string类的接口实现 1.构造函数,析构函数,拷贝构造函数,赋值重载 (1)构造函数 (2)析构函数 (3)拷贝构造函数 &…...

网页制作中的MVC和MVT

MVC(模型-视图-控制器)和MVT(模型-模板-视图)是两种常见的软件架构模式,通常用于Web应用程序的设计。它们之间的主要区别在于各自的组件职责和工作方式。 MVC(模型-视图-控制器): 模…...

02 - spring security基于配置文件及内存的账号密码

spring security基于配置的账号密码 文档 00 - spring security框架使用01 - spring security自定义登录页面 yml文件中配置账号密码 spring:security:user:name: adminpassword: 123456yml文件中配置账号密码后,控制台将不再输出临时密码 基于内存的账号密码 …...

Firebase Studio:开启 AI 驱动的开发新纪元

Firebase Studio(前身为 Project IDX)的推出,标志着软件开发范式正经历深刻变革。它不仅是一个传统的 IDE,更是一个以 AI 为主导的、代理式 (agentic) 的云端开发环境,专注于全栈 AI 应用(包括 API、后端、…...

网络基础2

目录 跨网络传输流程 网络中的地址管理 - 认识 IP 地址 跨网络传输 报文信息的跨网络发送 IP地址的转化 认识端口号 端口号范围划分 源端口号和目的端口号 认识 TCP / UDP协议 理解 socket 网络字节序 socket 编程接口 sockaddr 结构 我们继续来学习网络基础 跨网…...

Maven工具学习使用(十一)——部署项目到仓库

1、使用Maven默认方式 Maven 部署项目时默认使用的上传文件方式是通过 HTTP/HTTPS 协议。要在 Maven 项目中配置部署,您需要在项目的 pom.xml 文件中添加 部分。这个部分定义了如何部署项目的构件(如 JAR 文件)到仓库。。这个部分定义了如何…...

FPGA 37 ,FPGA千兆以太网设计实战:RGMII接口时序实现全解析( RGMII接口时序设计,RGMII~GMII,GMII~RGMII 接口转换 )

目录 前言 一、设计流程 1.1 需求理解 1.2 模块划分 1.3 测试验证 二、模块分工 2.1 RGMII→GMII(接收方向,rgmii_rx 模块) 2.2 GMII→RGMII(发送方向,rgmii_tx 模块) 三、代码实现 3.1 顶层模块 …...

torch.cat和torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于组合张量的两个常用函数,它们的核心区别在于输入张量的维度和输出张量的维度变化。以下是详细对比: 1. torch.cat (Concatenate) 作用:沿现有维度拼接多个张量,不创建新维度 输入要求…...

索引下推(Index Condition Pushdown, ICP)

概念 索引下推是一种数据库查询优化技术,通过在存储引擎层面应用部分WHERE条件来减少不必要的数据读取。它特别适用于复合索引的情况,因为它可以在索引扫描阶段就排除不符合全部条件的数据行,而不是将所有可能匹配的记录加载到服务器层再进行…...

C++基础精讲-06

文章目录 1. this指针1.1 this指针的概念1.2 this指针的使用 2. 特殊的数据成员2.1 常量数据成员2.2 引用数据成员2.3 静态数据成员2.4 对象成员 3. 特殊的成员函数3.1 静态成员函数3.2 const成员函数3.3 mutable关键字 1. this指针 1.1 this指针的概念 1.c规定,t…...

Django3 - 建站基础

学习开发网站必须了解网站的组成部分、网站类型、运行原理和开发流程。使用Django开发网站必须掌握Django的基本操作,比如创建项目、使用Django的操作指令以及开发过程中的调试方法。 一、网站的定义及组成 网站(Website)是指在因特网上根据一定的规则,…...

UE5蓝图设置界面尺寸大小

UE5蓝图设置界面尺寸大小 Create widget 创建UIadd to Viewport 添加视图get Game User Settings获取游戏用户设置set Screen Resolutions 设置屏幕尺寸大小1920*1080set Fullscreen Mode 设置全屏模式为:窗口化或者全屏Apply Settings 应用设置...

无数字字母RCE

无数字字母RCE&#xff0c;这是一个老生常谈的问题&#xff0c;就是不利用数字和字母构造出webshell&#xff0c;从而能够执行我们的命令。 <?php highlight_file(__FILE__); $code $_GET[code]; if(preg_match("/[A-Za-z0-9]/",$code)){die("hacker!&quo…...

AutoGen参数说明

UserProxyAgent用户 user_proxy = UserProxyAgent配置说明: # 构造参数 def __init__(self,name: str,is_termination_msg: Optional[Callable[[Dict], bool]] = None,max_consecutive_auto_reply: Optional[int] = None,human_input_mode: Literal["ALWAYS", &qu…...

6.2 GitHub API接口设计实战:突破限流+智能缓存实现10K+仓库同步

GitHub Sentinel 定期更新 API 接口设计 关键词:GitHub API 集成、异步爬虫开发、RESTful 接口设计、请求限流策略、数据增量更新 1. 接口架构设计原则 采用 分层隔离架构 实现数据采集与业务逻辑解耦: #mermaid-svg-WihvC78J0F5oGDbs {font-family:"trebuchet ms&quo…...

用java代码如何存取数据库的blob字段

一.业务 在业务中我们被要求将文件或图片等转成 byte[] 或 InputStream存到数据库的Blob类型的字段中. 二.Blob类型介绍 在 MySQL 中&#xff0c;Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型&#xff1a; TINYBLOB: 最大存储长度为 255 个字节。BL…...

2025蓝桥杯C++研究生组真题-上海市省赛

2025蓝桥杯C研究生组真题 A&#xff1a;数位倍数&#xff08;5分&#xff09; 问题描述&#xff1a;请问在 1 至 202504&#xff08;含&#xff09;中&#xff0c;有多少个数的各个数位之和是 5 的整数倍。例如&#xff1a;5、19、8025 都是这样的数。 A是填空题&#xff0c…...

原子操作CAS(Compare-And-Swap)和锁

目录 原子操作 优缺点 锁 互斥锁&#xff08;Mutex&#xff09; 自旋锁&#xff08;Spin Lock&#xff09; 原子性 单核单CPU 多核多CPU 存储体系结构 缓存一致性 写传播&#xff08;Write Propagation&#xff09; 事务串行化&#xff08;Transaction Serialization&#…...

Aspose.Words导出word,服务器用内存流处理,不生成磁盘文件

框架集&#xff1a;.NET8 public async Task<IActionResult> ExportPDF(long? id) {var infoawait form_Dahui_ReportDao.GetAsync(id);if (info null){return Content("没找到数据");}//读取word模板string fileTemp Path.Combine(AppContext.BaseDirect…...

攻防世界——Web题ez_curl

目录 Express PHP和Node.js的解析差异 Python代码 这道题最终得不到flag&#xff0c;用了很多师傅的代码也不成功。但还是需要学习 下载的附件&#xff1a; const express require(express);const app express();const port 3000; const flag process.env.flag;app.ge…...

力扣面试150题--螺旋矩阵

Day 20 题目描述 思路 根据题目描述&#xff0c;我们需要顺时针输出矩阵元素&#xff0c;顺时针说明有四种输出状态&#xff0c;横向从左到右和从右到左&#xff0c;纵向从上到下和从下到上&#xff0c;唯一的难点在于&#xff0c;输出完成一层后&#xff0c;如何进入内层&am…...

智能指针之设计模式2

前面介绍了工厂模式控制了智能指针和资源对象的创建过程&#xff0c;现在介绍一下智能指针是如何利用代理模式来实现“类指针&#xff08;like-pointer&#xff09;”的功能&#xff0c;并控制资源对象的销毁过程的。 2、代理模式 代理模式是为其它对象提供一种代理以控制对这…...

【Redis】redis持久化

Redis 持久化 Redis&#xff1a;非关系型的内存数据库 持久化&#xff1a;将数据永久写入磁盘&#xff08;内存→磁盘&#xff09; Redis 默认开启了持久化&#xff0c;默认模式为 RDB 为什么需要持久化&#xff1f; Redis 是内存数据库&#xff0c;宕机或关机后数据会丢失。…...

AtCoder Beginner Contest 401 E题 题解

E - Reachable Sethttp://E - Reachable Set 题意概述 &#xff1a; 给定一个无向图&#xff0c; 对于每个 &#xff0c;解决以下问题&#xff1a; -选择最少的一些顶点&#xff0c;使得删除这些顶点及其关联的所有边后 点1只能到达以内的所有点 牵制芝士 &#xff1a;头文…...

Kubernetes控制平面组件:API Server Webhook 授权机制 详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

【CodeMirror】系列(二)官网示例(六)自动补全、边栏

一、自动补全 codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。 自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能&#xff0c;比如HTML包。 默…...

CSS 表格样式学习笔记

CSS 提供了强大的工具来美化和定制 HTML 表格的外观。通过合理使用 CSS 属性&#xff0c;可以使表格更加美观、易读且功能强大。以下是对 CSS 表格样式的详细学习笔记。 一、表格边框 1. 单独边框 默认情况下&#xff0c;表格的 <table>、<th> 和 <td> 元…...

简单记录一下Android四大组件

1、Android Layout 1.1、LinearLayout 线性布局&#xff0c;子控件按照水平或垂直的方向依次排列&#xff0c;排列方向通过属性android:orientation控制&#xff0c;horizontal为水平排列&#xff0c;vertical为垂直排列。对于同一水平线上的控件&#xff0c;可以调整它的lay…...

在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布

2025年4月11日&#xff0c;人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括&#xff1a;数据源方面&#xff0c;Oracle数据源支持获取和查询物化视图&#xff1b;图表方面&#xff0c;在线地图支持天地图、腾讯地图&#xff1b;新增子弹图&…...