OpenCV学习(4.3) 图像阈值

1.目的

在本教程中:

  • 你会学到简单阈值法,自适应阈值法,以及 Otsu 阈值法(俗称大津法)等。
  • 你会学到如下函数:**cv.thresholdcv.adaptiveThreshold** 等。

2.简单阈值法

此方法是直截了当的。如果像素值大于阈值,则会被赋为一个值(可能为白色),否则会赋为另一个值(可能为黑色)。使用的函数是 cv.threshold。第一个参数是源图像,它应该是灰度图像。第二个参数是阈值,用于对像素值进行分类。第三个参数是 maxval,它表示像素值大于(有时小于)阈值时要给定的值。opencv 提供了不同类型的阈值,由函数的第四个参数决定。不同的类型有:

  • cv.THRESH_BINARY
  • cv.THRESH_BINARY_INV
  • cv.THRESH_TRUNC
  • cv.THRESH_TOZERO
  • cv.THRESH_TOZERO_INV

文档清楚地解释了每种类型的含义。请查看文档。

获得两个输出。第一个是 retval,稍后将解释。第二个输出是我们的阈值图像。

代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('gradient.png',0)
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in xrange(6):plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

在 OpenCV 中,这些是阈值化操作的类型,用于将灰度图像转换为二值图像或将灰度图像中的像素值根据阈值进行分割。阈值化是一种常见的图像处理技术,它根据像素值与设定阈值的比较结果,将像素值设置为0或最大值。

以下是这些阈值的类型及其作用:

  1. cv.THRESH_BINARY:如果像素值大于阈值,则将其设置为最大值(例如255),否则设置为0。这种类型的阈值化产生了一个完全黑白的二值图像。

  2. cv.THRESH_BINARY_INV:与cv.THRESH_BINARY相反,如果像素值大于阈值,则将其设置为0,否则设置为最大值。这种类型的阈值化也会产生一个完全黑白的二值图像,但与cv.THRESH_BINARY相比,黑色和白色的区域会互换。

  3. cv.THRESH_TRUNC:如果像素值大于阈值,则将其截断为阈值,否则保持不变。这种类型的阈值化不会产生二值图像,而是将阈值以上的像素值都设置为相同的值。

  4. cv.THRESH_TOZERO:如果像素值大于阈值,则保持不变,否则将其设置为0。这种类型的阈值化会将低于阈值的像素值变为黑色,而高于阈值的像素值保持其原始灰度。

  5. cv.THRESH_TOZERO_INV:与cv.THRESH_TOZERO相反,如果像素值大于阈值,则将其设置为0,否则保持不变。这种类型的阈值化会将高于阈值的像素值变为黑色,而低于阈值的像素值保持其原始灰度。

在使用这些阈值类型时,通常还会指定一个阈值值和一个最大值。阈值值是用于比较的值,而最大值是用于cv.THRESH_BINARYcv.THRESH_BINARY_INV类型的输出图像中的最大像素值。

 

3.自适应阈值 

在前一节中,我们使用一个全局变量作为阈值。但在图像在不同区域具有不同照明条件的条件下,这可能不是很好。在这种情况下,我们采用自适应阈值。在此,算法计算图像的一个小区域的阈值。因此,我们得到了同一图像不同区域的不同阈值,对于不同光照下的图像,得到了更好的结果。

它有三个“特殊”输入参数,只有一个输出参数。

Adaptive Method-它决定如何计算阈值。

  • cv.ADAPTIVE_THRESH_MEAN_C 阈值是指邻近地区的平均值。
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C 阈值是权重为高斯窗的邻域值的加权和。

Block Size-它决定了计算阈值的窗口区域的大小。

C-它只是一个常数,会从平均值或加权平均值中减去该值。

代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# img = cv.imread('gradient.png',0)
img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\04.jpg'
img = cv.imread(img,0)img = cv.medianBlur(img,5)
ret,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
th3 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)','Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in range(4):plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

img = cv.medianBlur(img,5)

在 OpenCV 中,cv.medianBlur 函数用于对图像进行中值滤波。中值滤波是一种非线性的数字图像滤波技术,它用像素点邻域内的中值来代替该像素点的值,从而消除图像中的椒盐噪声和斑点噪声,同时保持图像边缘清晰。 

在 OpenCV 中,可以使用 cv.adaptiveThreshold 函数来实现自适应阈值化。该函数的原型如下:

cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)

参数说明:

  • src:输入的灰度图像。
  • maxValue:用于阈值化操作的最大值,通常设置为 255。
  • adaptiveMethod:自适应方法,可以是 cv.ADAPTIVE_THRESH_MEAN_C 或 cv.ADAPTIVE_THRESH_GAUSSIAN_C
    • cv.ADAPTIVE_THRESH_MEAN_C:计算局部区域的平均值作为阈值。
    • cv.ADAPTIVE_THRESH_GAUSSIAN_C:计算局部区域的加权平均值作为阈值,权重是一个高斯窗口。
  • thresholdType:阈值类型,与 cv.threshold 函数中的阈值类型相同,例如 cv.THRESH_BINARY
  • blockSize:局部区域的大小,必须是奇数,如 3、5、7 等。
  • C:从平均值或加权平均值中减去的常数,通常是一个正值。

输出图像: 

4.otus二值化

在第一部分中,我告诉过您有一个参数 retval。当我们进行 Otsu 二值化时,它的用途就来了。那是什么?

在全局阈值化中,我们使用一个任意的阈值,对吗?那么,我们如何知道我们选择的值是好的还是不好的呢?答案是,试错法。但是考虑一个双峰图像(简单来说,双峰图像是一个直方图有两个峰值的图像)。对于那个图像,我们可以近似地取这些峰值中间的一个值作为阈值,对吗?这就是 Otsu 二值化所做的。所以简单来说,它会自动从双峰图像的图像直方图中计算出阈值。(对于非双峰图像,二值化将不准确。)

为此,我们使用了 cv.threshold 函数,但传递了一个额外的符号 cv.THRESH_OTSU 。对于阈值,只需传入零。然后,该算法找到最佳阈值,并作为第二个输出返回 retval。如果不使用 otsu 阈值,则 retval 与你使用的阈值相同。

查看下面的示例。输入图像是噪声图像。在第一种情况下,我应用了值为 127 的全局阈值。在第二种情况下,我直接应用 otsu 阈值。在第三种情况下,我使用 5x5 高斯核过滤图像以去除噪声,然后应用 otsu 阈值。查看噪声过滤如何改进结果。

代码:

import cv2 as cv
import numpy as np
from skimage import util
from matplotlib import pyplot as plt
# img = cv.imread('gradient.png',0)
img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\01.jpg'
img = cv.imread(img,cv.IMREAD_GRAYSCALE)
cv.imshow('img',img)# 全局阈值
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
# Otsu 阈值
ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# 经过高斯滤波的 Otsu 阈值
blur = cv.GaussianBlur(img,(5,5),0)
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# 画出所有的图像和他们的直方图
images = [img, 0, th1,img, 0, th2,blur, 0, th3]titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)','Original Noisy Image','Histogram',"Otsu's Thresholding",'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]for i in range(3):plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])plt.show()

 在您的代码中,您使用了 OpenCV 的 `cv.threshold` 函数来应用不同的阈值化方法。这里简要解释一下每个步骤:
1. `ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)`:
   - `img` 是输入图像。
   - `127` 是阈值。
   - `255` 是最大值。
   - `cv.THRESH_BINARY` 是阈值类型,它将像素值设置为 0 或 255,具体取决于它们是否大于阈值。
   - 返回值 `ret1` 是一个布尔值,表示阈值化操作是否成功。
   - `th1` 是阈值化后的输出图像。
2. `ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)`:
   - 与第一个步骤类似,但这次您使用了 `cv.THRESH_OTSU`。
   - `cv.THRESH_OTSU` 是一个特殊的阈值类型,它会自动选择一个阈值,使得前景和背景之间的类间方差最大。
   - `th2` 是应用 Otsu 阈值后的输出图像。
3. `blur = cv.GaussianBlur(img, (5, 5), 0)`:
   - `img` 是输入图像。
   - `(5, 5)` 是高斯滤波器的尺寸,它定义了滤波器的宽度和高度。
   - `0` 是高斯核的标准差,它决定了滤波器的模糊程度。
   - `blur` 是应用高斯滤波后的输出图像。
4. `ret3, th3 = cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)`:
   - 与第二个步骤类似,但这次您使用了经过高斯滤波的图像 `blur`。
   - `th3` 是应用 Otsu 阈值后的输出图像。
请注意,`cv.threshold` 函数的第二个参数 `0` 通常是不必要的,因为它是默认值。您可以直接使用 `cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)`。
最后,`ret1`、`ret2` 和 `ret3` 都是布尔值,表示阈值化操作是否成功。`th1`、`th2` 和 `th3` 是阈值化后的输出图像。

可以看到是没什么区别,因为图像噪声很小,进行高斯滤波后变化不大 

添加高斯噪声后,可以看到有明显的效果 

加入噪声的代码:
img = util.random_noise(img, mode='gaussian', mean=0, var=0.05)
img = np.uint8(img * 255)

在 OpenCV 中,util.random_noise(img, mode='gaussian', mean=0, var=0.05) 函数的 img 参数是一个图像数据,而 util.random_noise 函数是添加高斯噪声的函数。

当您调用 util.random_noise 函数并将 img 作为第一个参数传递时,它会根据您指定的参数(在这个例子中是 mode='gaussian'mean=0 和 var=0.05)为图像添加高斯噪声。

  • mode='gaussian' 指定使用高斯噪声模式。
  • mean=0 指定噪声的均值(中心点),这里设置为 0,意味着噪声的平均值是 0。
  • var=0.05 指定噪声的方差,它决定了噪声的强度。方差值越大,噪声越强。在这个例子中,方差为 0.05,意味着噪声强度较小。

添加噪声后,util.random_noise 函数将返回一个包含噪声的图像。这个图像的数据类型将与输入图像的数据类型相同。如果输入图像是一个浮点数图像,那么添加噪声后的输出也将是一个浮点数图像。如果输入图像是一个整数图像,那么添加噪声后的输出将是一个浮点数图像。

因此,util.random_noise(img, mode='gaussian', mean=0, var=0.05) 的输出结果将是一个浮点数图像,其中包含了根据指定参数添加的高斯噪声。

5. 二值化原理

 由于我们使用的是双峰图像,因此 Otsu 的算法试图找到一个阈值(t),该阈值将由下式计算得到的类内加权方差最小化。

它实际上找到一个 T 值,它位于两个峰值之间,使得两个类的方差最小。它可以简单地在 python 中实现,如下所示:

img = cv.imread('noisy2.png',0)
blur = cv.GaussianBlur(img,(5,5),0)
# 找到归一化直方图还有累计分布函数
hist = cv.calcHist([blur],[0],None,[256],[0,256])
hist_norm = hist.ravel()/hist.max()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1
for i in xrange(1,256):p1,p2 = np.hsplit(hist_norm,[i]) # 概率q1,q2 = Q[i],Q[255]-Q[i] # 类别总和b1,b2 = np.hsplit(bins,[i]) # 权重# f 找到均值与方差m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2# 计算最小函数fn = v1*q1 + v2*q2if fn < fn_min:fn_min = fnthresh = i
# 用 OpenCV 函数的 otsu'阈值
ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
print( "{} {}".format(thresh,ret) )

Q = hist_norm.cumsum()

在您提供的代码片段中,您正在计算直方图的累积分布函数(CDF)。累积分布函数(CDF)是概率论中的一个概念,它给出了随机变量小于或等于某个值的概率。在图像处理中,累积分布函数通常用于阈值选择,特别是在 Otsu 阈值化方法中。
在您的代码中,`Q = hist_norm.cumsum()` 意味着:
- `hist_norm` 是归一化的直方图,其值范围在 [0, 1]。
- `hist_norm.cumsum()` 计算直方图的累积和,即从左到右遍历直方图,计算累积的概率。
这个累积和形成了一个新的数组 `Q`,其中 `Q[i]` 表示随机变量小于或等于 `i` 的概率。这个数组 `Q` 就是累积分布函数(CDF)。
累积分布函数在 Otsu 阈值化方法中的作用是帮助选择一个阈值,使得背景和前景之间的类间方差最大。Otsu 阈值化的基本思想是找到一个阈值,使得前景和背景之间的类间方差最大。在这个上下文中,类间方差可以通过计算前景和背景的概率分布的方差来估计。
请注意,Otsu 阈值化通常使用 OpenCV 的 `cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)` 函数来实现,而不是手动计算累积分布函数。手动计算可能会导致不准确的结果,并且通常不如 OpenCV 的内置函数高效。 

p1,p2 = np.hsplit(hist_norm,[i]) # 概率

在您提供的代码片段中,您似乎正在尝试实现一个自定义的 Otsu 阈值选择方法。在这个方法中,您使用了 NumPy 的 `np.hsplit` 函数来分割直方图。
`np.hsplit` 函数用于将一个数组水平分割成多个子数组。它接受一个数组和一个或多个分割点作为参数,并将数组分割成多个子数组。
在您的代码中,`p1, p2 = np.hsplit(hist_norm, [i])` 意味着:
- `hist_norm` 是归一化的直方图。
- `[i]` 是分割点,表示您想要将直方图分割成两部分,其中一部分包含小于或等于 `i` 的像素,另一部分包含大于 `i` 的像素。
函数 `np.hsplit` 返回两个子数组,分别对应于小于或等于 `i` 的像素和大于 `i` 的像素。这两个子数组分别被赋值给 `p1` 和 `q2`。
请注意,如果您想要使用 OpenCV 的 `cv.threshold` 函数来应用 Otsu 阈值,您应该使用 `cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)`,而不是手动计算阈值。手动计算阈值可能会导致不准确的结果,并且通常不如 OpenCV 的内置函数高效。

q1,q2 = Q[i],Q[255]-Q[i] 

在您提供的代码片段中,您似乎正在尝试实现一个自定义的 Otsu 阈值选择方法。在这个方法中,您使用了累积分布函数(CDF)来分割直方图,并计算两个类别的概率。
在 Otsu 阈值化方法中,累积分布函数(CDF)被用来分割直方图,从而得到两个类别的概率分布。具体来说,您正在计算两个类别(前景和背景)的概率。
在您的代码中,`q1, q2 = Q[i], Q[255] - Q[i]` 意味着:
- `Q` 是累积分布函数(CDF)。
- `i` 是分割点,表示您想要将直方图分割成两部分,其中一部分包含小于或等于 `i` 的像素,另一部分包含大于 `i` 的像素。
- `Q[i]` 表示随机变量小于或等于 `i` 的概率,即背景的概率。
- `Q[255] - Q[i]` 表示随机变量大于 `i` 的概率,即前景的概率。
这两个概率值 `q1` 和 `q2` 用于后续的计算,以估计前景和背景的方差。Otsu 阈值化的基本思想是找到一个阈值,使得前景和背景之间的类间方差最大。类间方差可以通过计算前景和背景的概率分布的方差来估计。
请注意,Otsu 阈值化通常使用 OpenCV 的 `cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)` 函数来实现,而不是手动计算累积分布函数。手动计算可能会导致不准确的结果,并且通常不如 OpenCV 的内置函数高效。

b1,b2 = np.hsplit(bins,[i]) # 权重 

在您提供的代码片段中,您似乎正在尝试实现一个自定义的 Otsu 阈值选择方法。在这个方法中,您使用了 NumPy 的 `np.hsplit` 函数来分割一个包含像素值的数组。
在您的代码中,`b1, b2 = np.hsplit(bins, [i])` 意味着:
- `bins` 是一个包含像素值的数组,这些像素值代表图像的灰度级。
- `[i]` 是分割点,表示您想要将像素值数组分割成两部分,其中一部分包含小于或等于 `i` 的像素值,另一部分包含大于 `i` 的像素值。
函数 `np.hsplit` 返回两个子数组,分别对应于小于或等于 `i` 的像素值和大于 `i` 的像素值。这两个子数组分别被赋值给 `b1` 和 `b2`。
在 Otsu 阈值化方法中,`b1` 和 `b2` 通常被称为权重,它们代表图像中不同灰度级像素的数量。这些权重被用来计算前景和背景的加权方差,从而找到最佳的阈值。
请注意,Otsu 阈值化通常使用 OpenCV 的 `cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)` 函数来实现,而不是手动计算权重。手动计算可能会导致不准确的结果,并且通常不如 OpenCV 的内置函数高效。

m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2 v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2

在您提供的代码片段中,您似乎正在尝试实现一个自定义的 Otsu 阈值选择方法。在这个方法中,您正在计算两个类别(前景和背景)的均值和方差。
在 Otsu 阈值化方法中,均值和方差被用来估计前景和背景的加权方差,从而找到最佳的阈值。加权方差是类内方差和类间方差的组合,用于评估不同阈值下的分割质量。
在您的代码中,`m1, m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2` 意味着:
- `p1` 和 `p2` 是前景和背景的概率分布。
- `b1` 和 `b2` 是前景和背景的权重,即对应灰度级的像素数量。
- `q1` 和 `q2` 是前景和背景的概率。
这些概率和权重被用来计算两个类别的均值:
- `m1` 是前景的均值,计算方法是将前景的概率分布 `p1` 乘以前景的权重 `b1`,然后除以前景的概率 `q1`。
- `m2` 是背景的均值,计算方法是将背景的概率分布 `p2` 乘以背景的权重 `b2`,然后除以背景的概率 `q2`。
接着,您计算了两个类别的方差:
- `v1` 是前景的方差,计算方法是将前景的权重 `b1` 与前景的均值 `m1` 的差的平方乘以前景的概率分布 `p1`,然后除以前景的概率 `q1`。
- `v2` 是背景的方差,计算方法是将背景的权重 `b2` 与背景的均值 `m2` 的差的平方乘以背景的概率分布 `p2`,然后除以背景的概率 `q2`。
这些方差和均值值用于后续的计算,以估计前景和背景的加权方差,从而找到最佳的阈值。
请注意,Otsu 阈值化通常使用 OpenCV 的 `cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)` 函数来实现,而不是手动计算均值和方差。手动计算可能会导致不准确的结果,并且通常不如 OpenCV 的内置函数高效。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

word2016版本中同时显示多个页面

为了方便查看word内容&#xff0c;我们会将多个页面同时显示。 对于2016版&#xff0c;操作方法如下&#xff1a; 视图 ---》多页

Jan任意文件读取/下载和上传漏洞

自从ChatGPT横空出世以来&#xff0c;我一直想找一个可以自己训练的AI大模型&#xff0c;然而在使用Jan的过程中&#xff0c;数据包中传递的参数引起了我的兴趣&#xff0c;简单尝试后发现了任意文件读取和任意文件上传漏洞。 简介 Jan是ChatGPT的开源替代品&#xff0c;它在…

vuInhub靶场实战系列--bulldog-1

免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关。 目录 免责声明前言一、环境配置1.1 靶场信息1.2 靶场配置 二、信息收集2.1 主机发现2.1.1 netdiscover2.1.2 nmap主机扫描2.1.3 arp-scan主机扫描 2.2 端口扫描…

友思特案例 | 自动快速定位:使用波长选择器测量滤光片的关键光学性能指标

导读 光学滤光片检测的手动调节校准的传统方法存在诸多不确定误差和高昂的成本消耗。友思特全自动可调谐光源检测解决方案&#xff0c;可全自动调节波长带宽&#xff0c;快速收集光谱数据&#xff0c;缩短检测时间、降低质检成本&#xff0c;实现极高的准确率和快速检测效率。…

RA8D1-Vision Board上OSPI-Flash实践

Vision-Board 开发板是 RT-Thread 推出基于瑞萨 Cortex-M85 架构 RA8D1 芯片,拥有Helium和TrustZone技术的加持,性能非常强大。 内核:480 MHz Arm Cortex-M85,包含Helium和TrustZone技术 存储:集成2MB/1MB闪存和1MB SRAM(包括TCM,512KB ECC保护) 外设:兼容xSPI的四线O…

如何在强数据一致性要求下设计数据库的高可用架构

在高可用的三大架构设计(基于数据层的高可用、基于业务层的高可用,以及融合的高可用架构设计)中。仅仅解决了业务连续性的问题:也就是当服务器因为各种原因,发生宕机,导致MySQL 数据库不可用之后,快速恢复业务。但对有状态的数据库服务来说,在一些核心业务系统中,比如…

运营商卷大模型,云厂商霸主地位不保?

文&#xff5c;艺 思 编&#xff5c;王一粟 经过了2023年的小试牛刀&#xff0c;2024年&#xff0c;三大运营商带着大模型一路狂飙。 刚刚过去的5月&#xff0c;中国电信、中国移动、中国联通三大运营商集体完成了新一轮的大模型进化&#xff0c;特别是围绕大模型的研发与…

04--Tomcat

前言&#xff1a;本章整理tomcat的知识点&#xff0c;tomcat知识点相较nginx比较少&#xff0c;但是也是运维必会的软件&#xff0c;这里结合实际项目整理一下。 1、tomcat简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#x…

强烈安利10款手机App!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 1.听书神器——昊昊听书 昊昊听书app是一款专门为用户提供有声读物的应用程序。它不仅提供了各种类型的有声书籍&#xff0c;还有各种知名的电…

pw命令1

1、查看集群状态命令 gs_om -t status --detail 2、备节点升主&#xff08;本例子升2节点为主&#xff09; date && time cm_ctl switchover -n 2 -D /database/panweidb/data 3、cm_ctl是全局的&#xff0c;在一个节点运行 cm_ctl stop && cm_ctl start 就重…

铸铁机械5G智能工厂工业物联数字孪生平台,推进制造业数字化转型

铸铁机械5G智能工厂工业物联数字孪生平台&#xff0c;推进制造业数字化转型。工业物联数字孪生平台以5G技术为基础&#xff0c;通过工业物联网连接铸铁机械生产过程中的各个环节&#xff0c;运用数字孪生技术构建虚拟工厂&#xff0c;实现生产过程的实时监测、模拟与优化&#…

C语言的printf输出问题

看到这段代码的时候&#xff0c;想到这个printf输出的值是多少? 若您想到的答案是1-2&#xff0c;真的是这样吗&#xff1f; #include <stdio.h>int main(int argc, char *argv[]) {int i 1;printf("%d-%d\r\n", i, i);return 0; }先了解一个知识点&#xf…

I.MX6ULL UART 串口通信实验

系列文章目录 I.MX6ULL UART 串口通信实验 I.MX6ULL UART 串口通信实验 系列文章目录一、前言二、I.MX6U 串口简介2.1 UART 简介2.2 I.MX6U UART 简介 三、硬件原理分析四、实验程序编写五、编译下载验证5.1编写 Makefile 和链接脚本5.2 编译下载 一、前言 不管是单片机开发还…

解锁用Mermaid绘制图表的神奇力量

在这个快节奏、信息爆炸的时代&#xff0c;我们迫切需要一种简单、高效且美观的方式来表达复杂的思想和流程。 幸运的是&#xff0c;Mermaid就是这样一种工具。无论你是开发者、项目经理还是设计师&#xff0c;Mermaid都能帮助你轻松绘制各种类型的图表&#xff0c;让你的文档…

免费开源图片转文字识别软件:Umi-OCR

目录 1.介绍 2.项目亮点 3.项目功能&#xff08;已实现&#xff09; 4.功能体验 5.项目集成&#xff08;调用接口&#xff09; 6.项目地址 1.介绍 Umi-OCR&#xff1a;免费&#xff0c;开源&#xff0c;可批量的离线OCR软件&#xff0c;目前适用于 Windows7 x64 及以上。…

自动化办公02 用openpyxl库操作excel.xlsx文件(新版本)

目录 一、文件读操作 二、文件写操作 三、修改单元格样式 openpyxl 是一个处理Excel表格的第三方库。openpyxl 库可以处理Excel2010以后的电子表格格式&#xff0c;包括&#xff1a;xlsx/xlsm/xltx/xltm。 openpyxl教程 一、文件读操作 工作簿(workbook): excel文件 工作表…

word自带公式编辑器技巧

1.实现多行公式换行且对齐 1.1 准备阶段&#xff08;默认Unicode模式&#xff09; 进入公式编辑模式&#xff0c;输入\eqarray&#xff0c;紧接着按下空格键输入空格&#xff0c;如下 1.2 实现换行和对齐 将要编辑的公式输入到括号内 &&#xff1a;实现位置对齐 &…

104.网络游戏逆向分析与漏洞攻防-装备系统数据分析-筛选与装备有关的数据包

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

postman教程-15-前置脚本

上一小节我们学习了Postman生成随机数的方法&#xff0c;本小节我们讲解一下Postman前置脚本的使用方法。 Postman中的前置脚本&#xff08;Pre-request Script&#xff09;允许你在发送请求之前运行JavaScript代码。这可以用于修改请求头、查询参数、请求体等&#xff0c;或者…

web学习笔记(六十二)

目录 1.键盘事件 2.KeepAlive 3.组件传值 3.1 兄弟组件传值 3.2 组件树传值 3.3 发布订阅者传值 1.键盘事件 keydown表示键盘事件&#xff0c;在不加修饰符的情况下&#xff0c;点击键盘上的任意位置都可以触发键盘事件&#xff0c; <template><div><!--…