OpenCV 图像处理六(傅里叶变换、模板匹配与霍夫变换)

文章目录

  • 一、傅里叶变换
    • 1.1 NumPy实现和逆实现
      • 1.1.1 NumPy实现傅里叶变换
        • Demo
      • 1.1.2 NumPy实现逆傅里叶变换
        • Demo
    • 1.2 OpenCV实现和逆实现
      • 1.2.1 OpenCV实现傅里叶变换
        • Demo
      • 1.2.2 OpenCV实现逆傅里叶变换
        • Demo
    • 1.3 频域滤波
      • 1.3.1低频、高频
      • 1.3.2 高通滤波器
        • 构造高通滤波器
        • Demo
      • 1.3.3 低通滤波器
        • 设置低通滤波器
        • Demo
  • 二、模板匹配
    • 2.1 模板匹配是使用函数 cv2.matchTemplate()实现的。
    • 2.2 依据method获取想要的最值及其位置需要以使cv2.minMaxLoc()函数实现
      • 2.2.1 选择
      • 2.2.2 显现标记匹配位置
      • 2.2.3 Demo
  • 三、霍夫变换
    • 3.1 霍夫直线变换 -- HoughLines函数
      • 3.1.1 cv2.line()可以在图像上绘制直线,即使直线的端点坐标超出了图像的范围,也可以正确地绘制。
      • 3.1.2 Demo
    • 3.2 概率霍夫变换 cv2.HoughLinesP
    • 3.3 霍夫圆环变换

一、傅里叶变换

任何周期函数都可以表示为不同频率的正弦函数和的形式。

在这里插入图片描述

傅里叶变换(空间域变换到频率域)、 逆傅里叶变换(频率域信息变换到空间域)
(1)幅度图像(Magnitude Image)和相位图像(Phase Image):幅度图像显示了每个频率分量的强度或能量信息,它的取值范围是非负的。相位图像显示了每个频率分量的相位信息,它的取值范围通常是[-π, π]。通过显示幅度图像和相位图像可以很直观地观察到图像中不同频率分量的贡献和相位信息。
(2)实数图像和虚数图像:实数图像和虚数图像是将复数的傅里叶变换结果分别表示为实部和虚部的图像。实数图像显示了图像中的低频信息,而虚数图像则显示了图像中的高频信息。这种可视化方法将复数形式的傅里叶变换结果拆分为两个部分,更加直观地展示了图像中不同频率分量的特点。

1.1 NumPy实现和逆实现

通过傅里叶变换可以将图像分解为不同频率分量,并且频率越高的分量对应于图像中变化越快的部分,即边缘和细节等。而频率越低的分量对应于图像中变化缓慢的部分,即平滑区域和低频信号等。这种分解可以帮助我们进行频域滤波、图像恢复和特征提取等图像处理任务。

1.1.1 NumPy实现傅里叶变换

函数:
(1)

#实现变化,返回的是一个复数数组
np.fft.fft2

在这里插入图片描述

(2)

# 将零频率分量移动到中心
np.fft.ffshift

不加shift
在这里插入图片描述
加shift
在这里插入图片描述

(3)

# 设置批频谱的范围
magnitude_spectrum = 20*np.log(np.abs(fshift))
Demo
import numpy as np
import cv2  as cv
import matplotlib.pyplot as plt

img=cv.imread('./img/test_img.jpg',0)
f=np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img, cmap = 'gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('result')
plt.axis('off')
plt.show()

1.1.2 NumPy实现逆傅里叶变换

由频谱回到图像,在频域对图像进行处理,在频域的处理会反映在逆变换图像
(1)

# 实现逆傅里叶变换,返回应该复数数组
np.fft.ifft2

(2)

# 是fftshift逆函数
np.fft.ifftshift

(3)

# 设置值的范围
iimg=np.abs(逆傅里叶变换的结果)
Demo
import numpy as np
import  cv2 as cv
import matplotlib.pyplot as plt

img=cv.imread('./img/test_img.jpg',0)
#逆傅里叶变换
f=np.fft.fft2(img)
fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift)
iimg=np.fft.ifft2(ishift)
iimg=np.abs(iimg)
plt.subplot(131)
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.imshow(img, cmap = 'gray')
plt.title('original')
plt.axis('off')

plt.subplot(132)
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('magnitude_spectrum')
plt.axis('off')

plt.subplot(133)
plt.imshow(iimg, cmap = 'gray')
plt.title('result')
plt.axis('off')

在这里插入图片描述

1.2 OpenCV实现和逆实现

1.2.1 OpenCV实现傅里叶变换

(1)

#双通道,实数 、虚数
result=cv2.dft(原始图像,转换标识)

原始图像
首先被转换成np.float32格式,可以使用np.float32(img)来进行转换。

转换标识flags=cv2.DFT_COMPLEX_OUTPUT用于指定输出一个复数数组。

(2)

np.fft.ffshift

(3)用于计算复数的幅度的函数

result=cv2.magnitude(参数1,参数2

参数1和参数2是两个具有相同形状和数据类型的数组,分别表示复数的实部和虚部。

a + bi(其中 a 是实部,b 是虚部)
sqrt(a^2 + b^2)

Demo
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('./img/test_img.jpg', 0)
# 进行傅里叶变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 计算幅度谱
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(122)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.axis('off')
plt.show()

在这里插入图片描述
这段代码首先使用cv.imread()加载图像,然后使用cv.dft()进行傅里叶变换。接下来,使用np.fft.fftshift()将频率分量移动到图像中心。最后,通过cv.magnitude()计算复数的幅度,并使用20 * np.log()对结果进行缩放以便于显示。
注意:在这个例子中,傅里叶变换的结果是复数,cv.magnitude()用于计算复数的幅度并生成幅度谱。

1.2.2 OpenCV实现逆傅里叶变换

(1)

取决于元数据的类型和大小,双通道的
返回=cv.idft(原始数据)

(2)

 np.fft.ifftshift(magnitude_spectrum)

(3)

# 双通道的形式换成255的
cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])
Demo
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread('./img/test_img.jpg', 0)
# 进行傅里叶变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
# 进行逆傅里叶变换
fshift_inverse = np.fft.ifftshift(dft_shift)
img_back = cv.idft(fshift_inverse)
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])
# 显示图像对比
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.axis('off')
plt.subplot(133)
plt.imshow(img_back, cmap='gray')
plt.title('Inverse Fourier Transform')
plt.axis('off')
plt.tight_layout()
plt.show()

在这里插入图片描述

1.3 频域滤波

目的:图像增强、图像去噪、边缘检测、特征提取、压缩、加密等。

在图像中,低频分量表示颜色或灰度变化较为平缓的区域,通常对应图像中的平滑部分;

假设你正在拍摄一片平静的湖面。湖水的平静部分将对应低频分量,因为它们变化缓慢且颜色趋于一致。

高频分量表示变化较快、灰度过渡尖锐的区域,通常对应图像中的细节部分

观察一幅包含文字的图像时,文字的边缘对应高频分量。这是因为文字边缘通常具有锐利的灰度过渡,由于字体的笔画和字母之间的间隔。

1.3.1低频、高频

低通滤波器允许低频分量通过,同时衰减高频分量,从而模糊图像。这种滤波器可以用来平滑图像,去除噪声或减少图像中不必要的细节。

相反,高通滤波器允许高频分量通过,同时衰减低频分量,以增强图像中的尖锐细节。这会使图像更加清晰,但可能会导致对比度的降低。

1.3.2 高通滤波器

去除中心的fftshift

构造高通滤波器
# 构造高通滤波器
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)  # 中心位置
filter = np.ones_like(img)  # 创建与图像大小相同的滤波器
d = 30  # 高通滤波半径阈值
filter[crow - d: crow + d, ccol - d: ccol + d] = 0  #将中心d半径内的值设为0
Demo
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread('./img/test_img.jpg', 0)
# 进行傅里叶变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
# 构造高通滤波器
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)  # 中心位置
filter = np.ones_like(img)  # 创建与图像大小相同的滤波器
d = 30  # 高通滤波半径阈值
filter[crow - d: crow + d, ccol - d: ccol + d] = 0  #将中心d半径内的值设为0
# 进行滤波操作
fshift_filtered = fshift * filter
# 进行傅里叶逆变换
f_ishift = np.fft.ifftshift(fshift_filtered)
img_filtered = np.fft.ifft2(f_ishift)
img_filtered = np.abs(img_filtered)
# 显示结果
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Original')
plt.axis('off')
plt.subplot(132)
plt.imshow(np.log(1 + np.abs(fshift)), cmap='gray')
plt.title('Magnitude Spectrum')
plt.axis('off')
plt.subplot(133)
plt.imshow(img_filtered, cmap='gray')
plt.title('Filtered Image')
plt.axis('off')
plt.show()

在这里插入图片描述

1.3.3 低通滤波器

去除边缘的fftshift

设置低通滤波器
# 设置低通滤波器
rows, cols = img.shape
crow, ccol = rows//2, cols//2
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1  # 选择中心区域作为低频成分
Demo
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread('./img/test_img.jpg', 0)
# 进行傅里叶变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 设置滤波器
rows, cols = img.shape
crow, ccol = rows//2, cols//2
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1  # 选择中心区域作为低频成分
# 进行频域滤波
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])
# 显示原图和滤波后的图像
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(122)
plt.imshow(img_back, cmap='gray')
plt.title('Low Pass Filtered Image')
plt.axis('off')
plt.tight_layout()
plt.show()

模糊了,平滑图像,去除噪声在这里插入图片描述

二、模板匹配

在模板匹配中,通常将图像A称为输入图像或源图像,将图像B称为模板图像或搜索图像。模板匹配的目标是在输入图像中寻找与模板图像最相似的部分。

2.1 模板匹配是使用函数 cv2.matchTemplate()实现的。

result = cv2.matchTemplate(image, templ, method, result=None, mask=None)

参数
image – 运行搜索的图像。它必须是 8 位或 32 位浮点。
templ – 搜索的模板。它不能大于源图像,并且具有相同的数据类型。
result是一个单通道 32 位浮点型。如果输入图像(原始图像)尺寸是 WH,模板的尺寸是 wh, 则返回值的大小为(W-w+1)*(H-h+1)。

method
在这里插入图片描述
说明
在这里插入图片描述
(1)对于cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED方法,匹配结果的值越小,表示匹配程度越高。即匹配结果最小的位置是最佳的匹配位置。
(2)对于cv2.TM_CCORRcv2.TM_CCORR_NORMEDcv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED方法,匹配结果的值越大,表示匹配程度越高。即匹配结果最大的位置是最佳的匹配位置。
(3)通过比较匹配结果的值,可以确定模板与输入图像的匹配程度。较小的值或较大的值表示较好的匹配。具体的阈值和判断标准可以根据具体的应用场景和需求来确定。通常,我们会选择一个阈值,当匹配结果超过或低于该阈值时,判定为有效的匹配或无效的匹配。这个阈值的选择可以根据实验和经验来进行调整。

2.2 依据method获取想要的最值及其位置需要以使cv2.minMaxLoc()函数实现

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc( src [, mask] )

src:单通道的输入数组。

minVal:返回的最小值,如果没有最小值,则可以是空值。

maxVal:返回的最大值,如果没有最大值,则可以是空值。

minLoc:最小值的位置,如果没有最小值,则可以是空值。

maxLoc:最大值的位置,如果没有最大值,则可以是空值。

mask 为用来选取掩模的子集

2.2.1 选择

(1)当 method 的值为 cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED 时,0 表示最佳匹配,值越大表示匹配效果越差。因此,在使用这两种方法时,要寻找最小值所在的位置作为最佳匹配

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(matchTemplate 函数的返回值
topLeft = minLoc

# 以 topLeft 点为模板匹配位置的左上角坐标,
#根据模板图像的宽度和高度确定匹配位置的右下角坐标
bottomRight = (topLeft[0] + w, topLeft[1] + h) #w 和 h 是模板图像的宽度和高度

(2)当 method 的值为cv2.TM_CCORRcv2.TM_CCORR_NORMEDcv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED 时,cv2.matchTemplate() 函数的返回值越小表示匹配度越差,而返回值越大表示匹配度越好。

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(matchTemplate 函数的返回值
topLeft = maxLoc

# 以 topLeft 点为模板匹配位置的左上角坐标,
#根据模板图像的宽度和高度确定匹配位置的右下角坐标
bottomRight = (topLeft[0] + w, topLeft[1] + h)  # w 和 h 是模板图像的宽度和高度

2.2.2 显现标记匹配位置

rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)

在这里插入图片描述

2.2.3 Demo

TM_SQDIFF
topLeft = minLoc

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img/x.jpg')
template = cv2.imread('img/x1.jpg')
th, tw,tl = template.shape
rv = cv2.matchTemplate(img,template,cv2.TM_SQDIFF)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
topLeft = minLoc
bottomRight = (topLeft[0] + tw, topLeft[1] + th)
cv2.rectangle(img,topLeft, bottomRight, (0,255,0), 30)
plt.subplot(121),plt.imshow(rv,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img[:,:,::-1])
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

cv2.TM_CCOEFF
topLeft = maxLoc

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img/x.jpg')
template = cv2.imread('img/x1.jpg')
th, tw ,tl= template.shape
rv = cv2.matchTemplate(img, template, cv2.TM_CCOEFF)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
# 将变量名更新为对应的最大值
topLeft = maxLoc
bottomRight = (topLeft[0] + tw, topLeft[1] + th)
# 绘制矩形框
cv2.rectangle(img, topLeft, bottomRight, (0, 255, 0), 30)
# 显示结果
plt.subplot(121), plt.imshow(rv, cmap='gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img[:,:,::-1])
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

三、霍夫变换

霍夫变换(Hough Transform)是一种用于在数字图像中检测几何形状的技术。用于检测直线形状,还有其他如圆、椭圆等。

3.1 霍夫直线变换 – HoughLines函数

lines = cv2.HoughLines(image, rho, theta, threshold)

image:输入图像,通常为二值化图像(单通道,黑白)

rho:以像素为单位的距离精度,一般为1

theta:以弧度为单位的角度精度,一般为 np.pi/180

threshold:阈值,检测到的直线必须满足的投票数阈值

函数返回一个包含检测到的直线参数(rho和theta值)的数组,每一行表示一条检测到的直线。
使用霍夫直线变换函数,我们可以在图像中检测直线并对其进行分析、处理或绘制。

3.1.1 cv2.line()可以在图像上绘制直线,即使直线的端点坐标超出了图像的范围,也可以正确地绘制。

cv2.line(image, start_point, end_point, color, thickness)

image:要在其上绘制线段的图像

start_point:线段的起始点坐标,格式为 (x, y)

end_point:线段的结束点坐标,格式为 (x, y)

color:线段的颜色,可以是一个整数值(灰度图像)或一个包含三个整数值的元组/列表(彩色图像),表示蓝色、绿色、红色的值(BGR顺序)

thickness:线段的粗细,默认值为1

3.1.2 Demo

import cv2
import numpy as np
# 读取图像
image = cv2.imread('img/S1.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray, 50, 150)
# 进行霍夫直线变换
lines = cv2.HoughLines(edges, 1, np.pi/180, 150)
# 绘制直线
if lines is not None:
    for line in lines:
        rho, theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        pt1 = (int(x0 + 1000*(-b)), int(y0 + 1000*(a)))
        pt2 = (int(x0 - 1000*(-b)), int(y0 - 1000*(a)))
        cv2.line(image, pt1, pt2, (0, 0, 255), 2)
# 显示结果
cv2.imshow('Lines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.2 概率霍夫变换 cv2.HoughLinesP

lines =cv2.HoughLinesP(image, rho, theta, threshold, minLineLength,
maxLineGap)

在这里插入图片描述

cv2.HoughLinesP()函数是Hough变换的改进版本,主要在直线检测算法上进行了改进和优化。
传统的Hough变换是基于参数空间的方法,需要遍历所有像素点和所有可能的直线参数来进行计算,计算量较大,效率较低。而cv2.HoughLinesP()函数采用了概率霍夫变换(Probabilistic Hough Transform)的方法,通过随机采样的方式来快速寻找直线。
概率霍夫变换通过随机选择一部分边缘点来计算直线方程,并根据这些点的相对位置进行线段的连接,而不是遍历整张图像的所有像素点。这种随机采样的方式能够大大减少计算量,提高直线检测的速度。
另外,cv2.HoughLinesP()函数还引入了两个新的参数:minLineLength和maxLineGap。minLineLength参数用于指定线段的最小长度,比这个长度短的线段将被舍弃。maxLineGap参数用于定义在同一行中被认为是一条线段的最大间隙。这两个参数的引入使得直线检测更加准确和灵活。

import cv2
import numpy as np
# 读取图像
image = cv2.imread("img8/testSobelimg.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray, 50, 150)
# 进行直线检测
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)
# 绘制检测到的直线
if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
# 显示图像
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.3 霍夫圆环变换

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

在这里插入图片描述

在这里插入图片描述

import cv2
import numpy as np

# 读取图像
image = cv2.imread('Pic/show.png', cv2.IMREAD_GRAYSCALE)

# 霍夫圆环变换参数设置
dp = 1  # 累加器分辨率与图像分辨率之比的倒数
minDist = 50  # 检测到的圆心之间的最小距离
param1 = 100  # Canny边缘检测阈值上限
param2 = 30  # 圆心累加器阈值
minRadius = 10  # 最小圆半径
maxRadius = 100  # 最大圆半径

# 进行霍夫圆环变换
circles = cv2.HoughCircles(image, cv2.HOUGH_GRADIENT, dp, minDist,
                           param1=param1, param2=param2,
                           minRadius=minRadius, maxRadius=maxRadius)

if circles is not None:
    circles_rounded = np.uint16(np.around(circles))

    for circle in circles_rounded[0, :]:
        center = (circle[0], circle[1])
        radius = circle[2]

        # 绘制圆和中心点
        cv2.circle(image, center, radius, (0, 255, 0), 3)
        cv2.circle(image, center, 3, (0, 0, 255), -1)

    # 显示结果图像
    cv2.imshow('Hough Circles', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

(1)当在这里插入图片描述
在这里插入图片描述

(2)当
在这里插入图片描述

在这里插入图片描述

(3)

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/373748.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jquery写表格,通过后端传值,并合并单元格

<!DOCTYPE html> <html> <head><title>Table Using jQuery</title><style>#tableWrapper {width: 100%;height: 200px; /* 设置表格容器的高度 */overflow: auto; /* 添加滚动条 */margin-top: -10px; /* 负的外边距值&#xff0c;根据实际…

Mac OS中创建适合网络备份的加密镜像文件:详细步骤与参数选择

这篇文章提供了在Mac OS中创建适合网络备份的加密镜像文件的详细步骤&#xff0c;同时探讨了在选择相关参数时的关键考虑因素&#xff0c;以确保用户能够安全、高效地存储和保护重要数据。 创建步骤 在Mac OS Monterey中&#xff0c;你可以使用“磁盘工具”&#xff08;Disk …

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏12(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言斧头动画控制配置拿出 待机和攻击动画代码控制攻击动画 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中&#xff0…

LRU缓存

有人从网络读数据&#xff0c;有人从磁盘读数据&#xff0c;机智的人懂得合理利用缓存加速数据的读取效率&#xff0c;提升程序的性能&#xff0c;搏得上司的赏识&#xff0c;赢得白富美的青睐&#xff0c;进一步走向人生巅峰~ LRU假说 LRU缓存&#xff08;Least Recently Used…

SQL--函数

概念 函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码在MySQL中 已经给我们提供了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。 那 么&#xff0c;函数到底在哪儿使用呢&#xff1f; 我…

【Python 实战】---- 实现向指定PDF指定页面指定位置插入图片

1. 需求 想要能否实现批量自动为多个pdf加盖不同六格虚拟章(不改变pdf原有分辨率和文字可识别性);改在pdf首页上方空白位置,一般居中即可;如可由使用者自主选择靠页边距更好,以便部分首页上方有字的文件时人工可微调位置。2. 需求分析 直接将 pdf 文件转换为图片,在将图…

飞天使-k8s知识点12-kubernetes散装知识点1-架构有状态资源对象分类

文章目录 k8s架构图有状态和无状态服务 资源和对象对象规约和状态 资源的对象-资源的分类元数据型与集群型资源命名空间 k8s架构图 有状态和无状态服务 区分有状态和无状态服务有利于维护yaml文件 因为配置不同资源和对象 命令行yaml来定义对象对象规约和状态 规约 spec 描述…

Unity_修改天空球

Unity_修改天空球 Unity循序渐进的深入会发现可以改变的其实很多&#xff0c;剖开代码逻辑&#xff0c;可视化的表现对于吸引客户的眼球是很重要的。尤其对于知之甚少的客户&#xff0c;代码一般很难说服客户&#xff0c;然表现确很容易。 非代码色彩通才&#xff0c;持续学习…

洞悉未来,解锁因果:2023年DataFunSummit因果推断在线峰会全景解读

随着大数据和人工智能的飞速发展&#xff0c;因果推断作为连接数据与决策的桥梁&#xff0c;正日益受到各行业的广泛关注。 在这样的背景下&#xff0c;2023年DataFunSummit因果推断在线峰会如期而至&#xff0c;汇聚了众多业界领袖和专家学者&#xff0c;共同探讨因果推断的最…

【Java从入门到精通】Java注释

Java 注释 在计算机语言中&#xff0c;注释是计算机语言的一个重要组成部分&#xff0c;用于在源代码中解释代码的作用&#xff0c;可以增强程序的可读性&#xff0c;可维护性。 Java 注释是一种在 Java 程序中用于提供代码功能说明的文本。 注释不会被编译器包含在最终的可…

FANUC机器人如何清除示教器右上角的白色感叹号?

FANUC机器人如何清除示教器右上角的白色感叹号&#xff1f; 如下图所示&#xff0c;示教器上显示白色的感叹号&#xff0c;如何清除呢&#xff1f; 具体可参考以下步骤&#xff1a; 按下示教器上白色的“i”键&#xff0c;如下图所示&#xff0c; 如下图所示&#xff0c;按…

Linux截图快捷键以及修改快捷键方式

1. 截图快捷键 初始快捷键如下 全屏截图并保存&#xff1a;AltPrint 选区截图并保存&#xff1a;ShiftPrint 全屏截图并复制到剪贴板&#xff1a;AltCtrlPrint 选区截图并复制到剪贴板&#xff1a;ShiftCtrlPrint 会保存到Pictures文件夹下面 2. 修改快捷键 打开Settings界面…

一文了解 ArrayList 的扩容机制

了解 ArrayList 在 Java 中常用集合类之间的关系如下图所示&#xff1a; 从图中可以看出 ArrayList 是实现了 List 接口&#xff0c;并是一个可扩容数组&#xff08;动态数组&#xff09;&#xff0c;它的内部是基于数组实现的。它的源码定义如下&#xff1a; public class A…

BEV感知算法学习

BEV感知算法学习 3D目标检测系列 Mono3D(Monocular 3D Object Detection for Autonomous Driving) 流程&#xff1a; 通过在地平面上假设先验&#xff0c;在3D空间中对具有典型物理尺寸的候选边界框进行采样&#xff1b;然后我们将这些方框投影到图像平面上&#xff0c;从而避…

Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧

技术背景 我们在做Android平台GB28181设备对接模块的时候&#xff0c;遇到这样的技术需求&#xff0c;开发者希望能以后台服务的形式运行程序&#xff0c;国标平台侧没有视频回传请求的时候&#xff0c;仅保持信令链接&#xff0c;有发起视频回传请求或语音广播时&#xff0c;…

安卓动态链接库文件体积优化探索实践

背景介绍 应用安装包的体积影响着用户下载量、安装时长、用户磁盘占用量等多个方面&#xff0c;据Google Play统计&#xff0c;应用体积每增加6MB&#xff0c;安装的转化率将下降1%。 安装包的体积受诸多方面影响&#xff0c;针对dex、资源文件、so文件都有不同的优化策略&…

TOP100-二叉数

1.94. 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xf…

计算机网络_1.5 计算机网络的性能指标

1.5 计算机网络的性能指标 一、总览二、常用的八个计算机网络性能指标1、速率&#xff08;1&#xff09;数据量&#xff08;2&#xff09;速率&#xff08;3&#xff09;数据量与速率中K、M、G、T的数值辨析&#xff08;4&#xff09;【练习1】计算发送数据块的所需时间 2、带宽…

活锁方案与自旋锁

问题 如何设置获取互斥量时的等待时间&#xff1f; 如果等待超时&#xff0c;如何避免死锁&#xff1f; 避免死锁 -- 设置等待超时 解决方案&#xff1a; 1、尝试获取第 1 个互斥量&#xff1a; 若成功&#xff0c;则转 2 执行&#xff1b;若失败&#xff0c;则等待&#x…

idea开发工具的简单使用与常见问题

1、配置git 选择左上角目录file->setting 打开&#xff0c;Version Control 目录下Git&#xff0c;选择git安装目录下的git.exe文件&#xff1b; 点击test&#xff0c;出现git版本&#xff0c;则表示git识别成功&#xff0c;点击右下角确认即可生效。 2、配置node.js 选…