第五章 图像处理
文章目录
- 前言
- 一、图像金字塔
- 1.高斯金字塔
- 2.拉普拉斯金字塔
- 二、图像轮廓
- 1. 轮廓提取
- 2. 轮廓绘制
- 3. 轮廓特征
- 4. 轮廓近似
- 5. 轮廓标记
- 三、模板匹配
- 四、直方图
- 1. 对比度
- 2. 绘制直方图
- 3. 均衡化
- 3.1 理论
- 3.2 代码
- 4. CLAHE
- 五、图像傅里叶变换
- 5.1 正弦平面波
- 5.2 二维傅里叶变换
- 5.3 二维傅里叶变换结果 F ( u , v ) F(u, v) F(u,v)
- 5.4 傅里叶变换的实现
- 5.5 傅里叶滤波
- 5.5.1 低通滤波
- 5.5.2 高通滤波
- 总结
前言
本章讲讲解图像处理相关内容,包括图像金字塔、图像轮廓模板提取、直方图、图像傅里叶变换等。
一、图像金字塔
- 含义: 图像金字塔是一种用于图像处理和计算机视觉的技术。它是一系列图像的集合,其中每个图像比前一个图像分辨率更低, 从而形成一种金字塔形的结构。这些图像可以由同一图像的不同分辨率版本生成,也可以是不同图像之间的扫描和缩小。
- 作用: 在图像增强中,可以将图像分解为一系列不同分辨率的图像,然后对每个分辨率级别的图像进行处理,最终将它们合成为一张增强后的图像。在图像检测中,可以使用金字塔技术进行对象的尺度不变性检测。在目标跟踪中,可以在不同的尺度上搜索目标。
1.高斯金字塔
- 向下采样(缩小 图片):
- 首先进行高斯滤波
- 去除偶数的行、列
- 向上采样(放大图片):
- 用零填充偶数行、列
[ 10 30 56 96 ] ⇒ [ 10 0 30 0 0 0 0 0 56 0 96 0 0 0 0 0 ] \begin{bmatrix} 10& 30\\ 56&96\end{bmatrix}\Rightarrow \begin{bmatrix} 10 & 0 & 30 & 0\\ 0& 0 & 0 & 0\\ 56& 0& 96 &0 \\ 0& 0& 0&0\end{bmatrix} [10563096]⇒ 10056000003009600000 - 对放大的图片进行高斯卷积,从而可对零值进行填充
- 用零填充偶数行、列
# 向上采样
cv2.pyrUp(src[, dst[, dstsize[, borderType]]]) -> dst
# 向下采样
cv2.pyrDown(src[, dst[, dstsize[, borderType]]]) -> dst
2.拉普拉斯金字塔
I i + 1 = I i − P y r U p ( p y r D o w n ( I i ) ) I_{i+1} = I_i - PyrUp(pyrDown(I_i)) Ii+1=Ii−PyrUp(pyrDown(Ii))
执行上面的公式,就能得到每一层的图像。
拉普拉斯金字塔和高斯金字塔是图像金字塔的两个重要概念,它们之间有以下不同点:
-
算法步骤不同:高斯金字塔是由原始图像不断进行下采样(降分辨率)和高斯滤波得到的,每次下采样都将图像的尺寸减半。而拉普拉斯金字塔则是由高斯金字塔依次上采样(放大)和减去对应的低分辨率图像得到的。
-
不同的金字塔目的:高斯金字塔主要用于图像降采样(缩小)和尺度空间分析,可以用于图像的尺度不变性特征描述,如SIFT、SURF算法等。拉普拉斯金字塔则主要用于对图像进行增强、边缘检测和图像融合等操作。
-
金字塔层数和大小:高斯金字塔的层数与原始图像的大小有关,尺寸越大,高斯金字塔的层数也就越多。而拉普拉斯金字塔通常与高斯金字塔大小相同,因为它是由高斯金字塔得到的。
-
局部特征信息:尽管可逆性和单尺度不变性有用,但仅仅用于描述局部特征时可能不够准确。因此,拉普拉斯金字塔通常能够提供比高斯金字塔更丰富的局部特征信息。
因此,根据不同的应用场景,可以选择高斯金字塔或拉普拉斯金字塔等适合的金字塔结构来处理图像。
二、图像轮廓
1. 轮廓提取
contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
其中:
image
:输入的图像,应该是二值图像,每个像素的值要么为0,要么为255,表示前景和背景两种颜色。mode
:轮廓检索模式,是一个枚举值,取值范围包括:cv2.RETR_EXTERNAL
:只检测最外层的轮廓,即只返回边缘轮廓;cv2.RETR_LIST
:检测所有的轮廓,并返回其完整的列表;cv2.RETR_CCOMP
:检测所有的轮廓,但只返回两级轮廓结构,即外层轮廓和内层轮廓;cv2.RETR_TREE
:检测所有的轮廓,并返回完整的轮廓树结构。
method
:轮廓近似方法,是一个枚举值,取值范围包括:cv2.CHAIN_APPROX_NONE
:存储所有的轮廓点,每个点的坐标(x,y)都存储;cv2.CHAIN_APPROX_SIMPLE
:仅保留轮廓的端点,只需存储它们的坐标即可,例如矩形轮廓仅需要4个点的坐标即可。
contours
:输出参数,返回检测到的轮廓,每个轮廓是一个由像素坐标表示的Numpy数组。hierarchy
:输出参数,返回轮廓的层级关系,每个轮廓由4个值(父级轮廓编号,下一级轮廓编号,第一个子级轮廓编号,前一个兄弟轮廓编号)
表示。
hierarchy的理解
2. 轮廓绘制
cv2.drawContours()
是OpenCV提供的一个函数,能够在图像中绘制轮廓。
该函数的语法如下:
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
参数解释如下:
image
: 要绘制轮廓的图像。contours
: 一个由轮廓点集组成的列表,可以通过cv2.findContours()
函数获取。该参数可以是一个单独的轮廓(Point集合),也可以是多个轮廓的列表。contourIdx
: 指定要绘制的轮廓的编号。如果是负数,则表示要绘制所有的轮廓。color
: 轮廓颜色,可以是RGB元组或BGR元组。thickness
: 轮廓线条粗细,默认值为1.lineType
: 线条类型,默认值为8-connectivity(即cv2.LINE_8),也可以设置为4-connectivity(即cv2.LINE_4)或CV_AA。hierarchy
: 轮廓层级信息,可选参数。maxLevel
: 可以绘制的轮廓的最大级别,可选参数。offset
: 轮廓计算的偏移量,可选参数。
3. 轮廓特征
在OpenCV中,对于图像中的轮廓,有许多特征可以用来描述和分析这些轮廓。下面列出了一些主要的轮廓特征:
-
轮廓面积:轮廓曲线所包含的面积大小,可以用
cv2.contourArea()
函数计算。 -
轮廓周长:轮廓曲线的长度,可以用
cv2.arcLength()
函数计算。 -
轮廓近似:通过降低轮廓点数目来近似表示轮廓形状,可以用
cv2.approxPolyDP()
函数进行处理。 -
轮廓重心:轮廓曲线所包含区域的质心点坐标,可以用
cv2.moments()
函数计算。 -
轮廓方向:轮廓曲线的方向,可以用
cv2.fitEllipse()
或cv2.minAreaRect()
函数分别拟合椭圆或矩形来计算。 -
轮廓凸包:包含轮廓曲线所有点的凸边形,可以用
cv2.convexHull()
函数计算。 -
轮廓缺陷:凸包与轮廓曲线之间的差距,可以用
cv2.convexityDefects()
函数计算。
这些轮廓特征可以结合使用,用来分析图像中的轮廓形状和特征。在实际应用中,轮廓特征常常被用来进行目标检测、图像分类和图像识别等任务。
4. 轮廓近似
- 原理:
首先连接A、B两点,然后在弧线AB上找一点,使得该点到直线AB上的距离最大,记该点为C,该距离为d,若d小于指定的数值,则用直线AB代替弧线AB,否则则以C为中间点,再分别判断弧线AC与弧线CB的近似。
在OpenCV中,cv2.approxPolyDP()
函数可以对轮廓进行近似处理,以减少轮廓点的数量,简化轮廓曲线,从而提高图像处理的效率。该函数的语法如下:
cv2.approxPolyDP(curve, epsilon, closed[, approxCurve])
参数解释如下:
curve
: 输入的轮廓,一般是一个由点组成的列表或Numpy数组。epsilon
: 指定近似程度,即对轮廓的最大误差。如果指定的距离小于epsilon,那么就会被认为是同一曲线上的点。closed
: 指定是否是闭合曲线,如果为True
,表示曲线是闭合的,否则为打开的曲线。approxCurve
: 输出的近似轮廓,可以是numpy数组或空对象。如果不指定输出数组,则函数会返回近似轮廓的坐标点数组。
该函数的返回值表示的是近似轮廓的坐标点,可以通过对输出数组的大小来确定近似后曲线上的点的数量。epsilon
的值受影响因素较多,需要根据具体情况进行设定。
近似处理的效果往往受到调节参数的影响,如果epsilon
设置得过小,处理得过度,则可能会丢失重要的轮廓信息;如果epsilon
设置得过大,则可能会保留过多的轮廓信息,增加了计算量,并且可能导致轮廓的误检和漏检等问题。因此,在进行轮廓近似时,需要根据具体情况进行参数的调适,以达到最佳的处理效果。
5. 轮廓标记
- 作用: 用一个形状(矩形、圆圈等)将轮廓标记出来。
# 背景画布
canvabg = img.copy()
# 获取轮廓
cnt0 = contours[0]
# 矩形边框
startx,starty,width,height = cv2.boundingRect(cnt0)
cv2.rectangle(canvabg,(startx,starty),(startx + width,starty + height),(0,255,0),2)
# 获取轮廓
cnt1 = contours[2]
# 圆圈外框
(cx,cy),radius = cv2.minEnclosingCircle(cnt1)
cv2.circle(canvabg,(int(cx),int(cy)),int(radius),(255,0,0),2)
三、模板匹配
- 思路: 将模板图片当作卷积核与被匹配的图像进行卷积操作,然后根据具体匹配算法计算出每一步卷积操作的置信度,根据置信度来确定模板图像在被匹配图像中的位置。
在OpenCV中,使用cv2.matchTemplate()
函数可以实现图像匹配的功能。图像匹配是指在一幅图片中查找某个感兴趣区域(通常是一个模板图像)在该图像中的位置和数量。
cv2.matchTemplate()
函数的语法如下:
cv2.matchTemplate(image, templ, method[, result[, mask]]) → result
参数解释如下:
image
: 输入图像,应该是8位或32位浮点型的灰度图像。templ
: 模板图像,在输入图像中查找的图像区域。与输入图像具有相同的数据类型和通道数。method
:-
平方差匹配(
cv2.TM_SQDIFF
):此匹配方法会依次比较输入图像和模板图像中像素点的差值平方,并返回差值的总和。匹配结果越小,匹配度越高。 -
归一化平方差匹配(
cv2.TM_SQDIFF_NORMED
):此匹配方法与平方差匹配方法类似,但会将匹配结果归一化,即匹配结果越小,匹配度越高。 -
相关匹配(
cv2.TM_CCORR
):此匹配方法将输入图像和模板图像进行互相关运算,并返回相关系数的最大值。匹配结果越大,匹配度越高。 -
归一化相关匹配(
cv2.TM_CCORR_NORMED
):此匹配方法与相关匹配方法类似,但会将匹配结果归一化,即匹配结果越大,匹配度越高。 -
系数匹配(
cv2.TM_CCOEFF
):此匹配方法会计算输入图像和模板图像之间的相关系数,然后从相关系数图像中找到最大值。匹配结果越大,匹配度越高。 -
归一化系数匹配(
cv2.TM_CCOEFF NORMED
):计算归一化相关系数,计算出来的值越接近1,越相关。
-
result
: 匹配结果,一般不需要指定该参数,函数会自动创建。其大小为输入图像大小减去模板图像大小加1,是一个二维数组。mask
: 遮罩,如果指定,则只在遮罩区域内进行模板匹配。
import numpy as np
import cv2
import matplotlib.pyplot as pltimg = cv2.imread("F:/MyOpenCV/ai.jpg")
imgTmp = cv2.imread("F:/MyOpenCV/aitemp.jpg")result = cv2.matchTemplate(img, imgTmp, cv2.TM_SQDIFF_NORMED)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)
x, y = minLoc
h, w, t = imgTmp.shape
cv2.rectangle(img, minLoc, (x + w, y + h), (255, 0, 0), 2)cv2.imshow("img", img)
cv2.imshow("imgsim", imgTmp)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、直方图
1. 对比度
- 定义: 对比度是指图像中最亮和最暗区域之间的差异度量,即白和黑之间的差异程度。在数字图像处理中,对比度可用于调整图像的明暗程度,通常是通过调整图像中像素的亮度和颜色值来实现。较高的对比度可以使图像更加清晰明亮,而较低的对比度则会使图像显得柔和、模糊或无法分辨。
2. 绘制直方图
直方图的横坐标为像素通道值的取值范围,纵坐标为数值出现的次数。
cv2.calcHist()
可以用于计算灰度图像的直方图,也可以用于计算彩色图像的直方图。
cv2.calcHist()
的语法如下:
hist = cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
参数说明如下:
images
: 输入的图像,以 numpy 数组的形式提供。如果要计算灰度图像的直方图,则images
的维度应该是二维的,而对于彩色图像,则应该是三维的,其中第三维表示图像的颜色通道。传递给函数的图像应该是一个列表,即使你只使用单个图像,也要将图像包装在列表中。channels
: 要统计的颜色通道的索引列表。对于灰度图像,此参数应该为[0]
,对于彩色图像,则通常是[0, 1, 2]
表示三个颜色通道。mask
: 可选的掩码图像,用于指定参与直方图计算的像素位置。只有在掩码图像中对应位置像素值为非零值时,才会将该位置的像素纳入直方图计算。histSize
: 直方图的bin数量,也就是区间数量。该参数应该为一个列表,每个元素表示一个通道的bin数量。ranges
: 直方图的像素值范围,也就是区间范围。该参数应该为一个列表,每个元素表示一个通道的像素值范围。hist
: 可选的输出直方图数组对象。accumulate
: 可选的累加标志。
cv2.calcHist()
的返回值是一个numpy数组,表示所计算的直方图。对于灰度图像,返回的是一维数组;对于彩色图像,返回的是一个三维数组,其中每个维度分别表示BGR三个通道的直方图。
img = cv2.imread("F:/MyOpenCV/hello.jpg")
b, g, r = cv2.split(img)
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)histGray = cv2.calcHist([imgGray], [0], None, [256], [0, 256])# 绘制直方图
plt.plot(histGray)
plt.xlim([0, 256])
plt.xlabel("灰度值")
plt.ylabel("像素数量")
plt.show()
注:也可以使用matplotlib的方法,
plt.hist(data, histSize)
其中data为直方图的一维数组,因此图像数据调用ravel
函数。
3. 均衡化
3.1 理论
- 目的: 将原图像通过变换,得到一幅灰度直方图的灰度值均匀分布的新图像。对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。从而达到清晰图像的目的。最理想的情况就是变换后,像素灰度概率完全一样的,但是实际上做不到那么平均。
3.2 代码
cv2.equalizeHist(src:image[, dst]) -> dst:image
4. CLAHE
-
直方图均衡化问题:
- 全局效果,导致原来比较亮的地方变得更亮 原来暗的地方变得更暗 从而会导致细节的丢失。
- 可能导致噪点的放大。
-
思路: 将图片进行拆分,然后分别对每个部分进行均衡化处理,且对每个部分的直方图概率分布做限制。
-
算法实现:
- 图像分块
- 找每个块的中心点
- 分别计算每个块的灰度直方图,并进行阈值限制
- 得到每个块的直方图分布后,根据直方图均衡化算法对每个块的中心点进行均衡化处理。只对中心点进行均衡化是为了加快计算速度。
- 根据中心点均衡化后的灰度值,利用差值算法计算图像块剩余像素的灰度值。
-
代码:
# 生成自适应均衡化算法 # clipLimit :阈值,1 表示不做限制。值越大,对比度越大 # tileGridSize:如何拆分图像 clahe = cv2.createCLAHE([, clipLimit[, tileGridSize]]) -> retval # 对像素通道进行自适应均值化处理 dst = clahe.apply(src)
cv2.createCLAHE 函数可接受三个参数,分别是 clipLimit、tileGridSize 和 tileGridSizeX(取代 tileGridSize),其中:
- clipLimit:保持对比度等级的限制值,这个值越小,保持的对比度等级越高;
- tileGridSize:将图像分成的矩形块的大小,以像素为单位。该参数应该是奇数。若在 tileGridSizeX 参数中指定,那么就不需要输入该参数。
- tileGridSizeX:同 tileGridSize,用于指定矩形块的大小。
五、图像傅里叶变换
- 扩展阅读
- 傅里叶变换
- 二维傅里叶变换
- 图像傅里叶
5.1 正弦平面波
- 直观定义: 将一维正弦曲线朝着纵向的一个方向上将其拉伸得到一个三维的波形,然后将波形的幅值变化用二维平面进行表示,再将二维平面波绘制成灰度图,从而波峰为255白色 波谷为0黑色,中间是一个灰度的过渡。
- 数学参数:
- 正弦波:频率w, 幅值A,相位 φ \varphi φ
- 拉伸方向:在二维坐标中,向量可以写为 n → = ( μ , v ) \overrightarrow{n} = (\mu, v) n=(μ,v)
5.2 二维傅里叶变换
- 思想: 二维傅里叶变换中,认为二维数据是由无数个
正弦平面波
所构成。
- 离散傅里叶变换公式:
F ( u , v ) = 1 M N ∑ x = 0 M − 1 ∑ y = 0 N − 1 f ( x , y ) e − i 2 π ( u x M + v y N ) F(u,v) = \frac{1}{MN}\sum_{x=0}^{M-1}\sum_{y=0}^{N-1}f(x,y)e^{-i2\pi(\frac{ux}{M}+\frac{vy}{N})} F(u,v)=MN1x=0∑M−1y=0∑N−1f(x,y)e−i2π(Mux+Nvy) - 参数的解释:
5.3 二维傅里叶变换结果 F ( u , v ) F(u, v) F(u,v)
- (u, v)拉伸方向的向量
- w = u 2 + v 2 w = \sqrt{u^2 + v^2} w=u2+v2 向量的模表示正弦波的频率
- F(u, v):复数, 隐含了正弦波的幅值A和相位 φ \varphi φ。详细的还是看上面的扩展阅读吧。
5.4 傅里叶变换的实现
OpenCV提供了dft(src:np.float[, dst[, flags[, nonzeroRows]]]) -> dst
来进行傅里叶变换,参数含义如下:
src
:输入的单通道图像,必须为浮点型dst
:输出的复数形式的结果,大小与src
一致flags
:变换操作的附加选项,通常可以设置为cv2.DFT_COMPLEX_OUTPUT
表示输出为复数nonzeroRows
:当输入图像的尺寸不是2的幂次方时,必须手动指定变换中心(如果输入图像大小为偶数,则默认中心为图像的中心,否则中心为左上角)n
:可选参数,指定变换的大小,通常为src
的尺寸- 返回值是是
双通道
,第一个通道是实部,第二个通道是虚部
注:由于离散傅里叶变换具有共轭对称性 因此只有四分之一是有效的其他是翻转的。
- 频谱图中心化:
方便用于滤波操作。# 频谱中心化 shiftA = np.fft.fftshift(A)
5.5 傅里叶滤波
- 思路:
- 对图像灰度进行傅里叶变换,得到频域结果
- 将要删除的频率所对应的傅里叶变换结果全部置为0+i0
- 对修改后的傅里叶变换结果进行傅里叶反变换
5.5.1 低通滤波
将低频部分的结果全部置为零
import numpy as np
import cv2
import matplotlib.pyplot as pltimg = cv2.imread("F:/MyOpenCV/ai.jpg")
yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
yfloat = np.float32(yuv[:, :, 0]) # 其实就是取了灰度图dft = cv2.dft(yfloat, flags=cv2.DFT_COMPLEX_OUTPUT) # 生成频谱图
dftShift = np.fft.fftshift(dft) # 中心化centerRow = int(dftShift.shape[0] / 2) # 宽的中心
centerCol = int(dftShift.shape[1] / 2) # 列的中心mask = np.zeros(dftShift.shape, dtype=np.uint8) # 构造一个掩膜
mask[centerRow - 30 : centerRow + 30, centerCol - 30 : centerCol + 30, :] = 1
dftShift = dftShift * mask # 按位乘dft = np.fft.ifftshift(dftShift) # 先反中心化
idft = cv2.idft(dft) # 再反傅里叶iyDft = cv2.magnitude(idft[:, :, 0], idft[:, :, 1]) # 转为实数
iy = np.uint8(iyDft / iyDft.max() * 255) # 映射yuv[:, :, 0] = iy
imgRes = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR)cv2.imshow("imgRes", imgRes)cv2.waitKey(0)
cv2.destroyAllWindows()
5.5.2 高通滤波
类似于低通 改一下掩膜就行 效果如下(有点恐怖 下次还是使用灰度图吧)
总结
最近在忙实验室的项目,本篇搞的有点慢,这两天把它弄完。
相关文章:

第五章 图像处理
文章目录 前言一、图像金字塔1.高斯金字塔2.拉普拉斯金字塔 二、图像轮廓1. 轮廓提取2. 轮廓绘制3. 轮廓特征4. 轮廓近似5. 轮廓标记 三、模板匹配四、直方图1. 对比度2. 绘制直方图3. 均衡化3.1 理论3.2 代码 4. CLAHE 五、图像傅里叶变换5.1 正弦平面波5.2 二维傅里叶变换5.3…...

算法8.从暴力递归到动态规划1
算法|8.从暴力递归到动态规划1 目前感觉,背包问题和货币数组问题本质相同,货币的与dp相关的三种代码写完了,快复习不完了,背包暂时先不写了,回头再写,补充,再总结,结合那个C大神的文…...

8-JDBC 编程
目录 1.数据库编程的必备条件 PS:程序是怎么操作数据库的? 2.什么是JDBC? 2.1.JDBC定义 2.2.JDBC工作原理 3.JDBC使用 3.1.创建项目并添加MySQL驱动包 3.2.使用代码操作数据库 3.2.1.获得数据源 3.2.2.获得连接 3.2.3.获得执行器 …...

零基础如何学习 Web 安全?
Web安全不仅是互联网的核心,而且还是云计算和移动互联网的最佳载体。对于信息安全从业者而言,Web安全是一个非常重要的研究课题之一。 Web应用是指采用B/S架构、通过HTTP/HTTPS协议提供服务的统称。随着互联网的广泛使用,社交网络、聊天工具…...

【简单实用框架】【AddressablesMgr】【可移植】
☀️博客主页:CSDN博客主页💨本文由 萌萌的小木屋 原创,首发于 CSDN💢🔥学习专栏推荐:面试汇总❗️游戏框架专栏推荐:游戏实用框架专栏⛅️点赞 👍 收藏 ⭐留言 📝&#…...
android 12.0Launcher3禁止拖拽app图标到第一屏
1.概述 在12.0进行定制化开发Launcher3中,会对Launcher3 做些要求,比如现在的需求就是Launcher3第一屏的图标固定,不让其他屏的图标拖动到 第一屏所以说这个需求和 禁止拖拽图标到Hotseat类似,也是从WorkSpace.java里面寻找解决方案 2.Launcher3禁止拖拽app图标到第一屏相…...
SkyLine简介
简介 SkyLine产品系列(TerraExplorer 、TerraGate、TerraBuilder)是一套优秀的三维数字地球平台软件。凭借其国际领先的三维数字化显示技术,它可以利用海量的遥感航测影像数据、数字高程数据以及其他二三维数据搭建出一个对真实世界进行模拟…...

算法基础学习笔记——④前缀和\差分\双指针\位运算
✨博主:命运之光 ✨专栏:算法基础学习 目录 ✨前缀和 ✨一维前缀和 🍓一维前缀和模板: ✨二维前缀和 🍓二位前缀和模板: 前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O&a…...
【Linux系统基础快速入门详解】Linux下安装软件必知必会4种方法(yum,编译安装,rpm包,二进制方式)等详解
在 Linux 下安装软件有多种方法可供选择,常用的包括 yum、编译安装、rpm 包和二进制方式。下面对这些方法进行详细说明: 使用 yum 安装软件yum 是 Red Hat 系列 Linux 发行版中常用的软件包管理工具,通过 yum 可以方便地安装、升级和删除软件包。yum 默认从官方仓库中下载软…...

ASEMI代理长电可控硅BT136参数,BT136规格,BT136说明
编辑-Z 长电可控硅BT136参数: 型号:BT136 RMS通态电流IT(RMS):6A 非重复浪涌峰值导通电流ITSM:25A 峰值栅极电流IGM:2A 平均栅极功耗PG(AV):0.5W 存储接点温度范围Tstg:-40 to 150℃ 工…...

代码线程安全
线程生命周期 synchronized synchronized会自动释放锁 synchronized同步代码块 synchronized后面括号里obj是锁对象(保证唯一);static修饰的obj对象是自定义MyThread线程类的静态成员变量,该自定义线程类所有实例共享保证锁对象唯一性;另一…...

Filebeat技术栈总结
filebeat 是一个轻量型日志采集器,本质上是一个 agent 。不依赖于任何应用,可以安装在任何节点上,可单独使用 Filebeat 并根据配置读取对应位置的日志进行上报和搜集。 filebeat 内置了常用的 output 组件,例如 kafka、ElasticSe…...
【App自动化测试】(十六)健壮性测试工具——Android Monkey
目录 1. 介绍2. 安装3. Monkey的使用4. money常用命令5. 常用事件类型参数6. Monkey使用参考 1. 介绍 Monkey是一个在模拟器或设备上运行的程序,用于生成用户事件的伪随机流。 为什么要使用Monkey这个自动化遍历工具? Monkey解决了一个测试痛点ÿ…...

实现第一个内核程序的Hello World
背景 在内核的开发中,总要先入个门。那么就要来编写第一个内核程序 入门 一个 module_init 程序是Linux内核模块的一部分,通过module_init 方法就能将程序载入内核。 module_init 方法需要以下步骤 编写module_init 的代码,并将其保存为…...

python基于协同过滤推荐算法的电影观后感推荐管理系统的设计
本课题所设计的影单管理系统,使用B/S架构,Python语言进行开发,它的优点代码不能从浏览器查看,保密性非常好,比其他的影单管理更具安全性。Python还容易修改和调试,毕竟影视是在不断发展过程中,难…...

Vue——状态管理库Pinia
写在前面:本文参考小满大牛的pinia专栏 一、Vuex与Pinia Vuex 和 Pinia 均是 Vue.js 的状态管理库,它们为 Vue 应用程序提供了一种集中式的、可预测的状态管理解决方案。 Vuex 是 Vue.js 官方推荐的状态管理库之一。它的核心概念包括 state、mutation…...

Linux:忘记root密码解决办法
如果你是虚拟机只要将光盘镜像连接到虚拟机上,以光盘iso镜像启动 如果你是真机或服务器那将实体u盘或实体光盘连接至设备并且以连接的设备启动 开机时候打断开机 使用 (u盘|光盘)引导启动 troubleshooting rescue a centos system 输入 1…...
Dockerfile(4) - RUN 指令详解
RUN 运行命令 shell 形式 命令在 shell 中运行Linux 上默认为 /bin/sh -cWindows 上 cmd /S /C RUN <command> exec 形式 RUN ["executable", "param1", "param2"] 必须双引号,不能是单引号 两种写法的实际栗子 RUN …...

一个完整的APP定制开发流程是怎样的?
随着移动互联网的发展,越来越多的 APP应用软件进入人们的生活,让我们的生活更便捷、更舒适。而随着互联网技术的进步,移动互联网应用软件开发行业也越来越成熟,为了适应市场需求,各种功能强大、性能良好的 APP应用软件…...

【数据结构】24王道考研笔记——线性表
线性表 目录 线性表定义和基本操作顺序表静态顺序表动态顺序表 链表单链表不带头结点:带头结点: 双链表循环链表循环单链表:循环双链表: 静态链表 顺序表链表比较逻辑结构:存储结构:基本操作: 定…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...