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.pswp.cn/web/22841.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/22841.shtml
英文地址,請注明出處:http://en.pswp.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…

gorse修改開源項目后,如何使用Docker compose發布

代碼修改 git checkout v0.4.15 修改代碼后提交。 鏡像構建 export GOOSlinux export GOARCHamd64 export GOMAXPROCS8go build -ldflags"-s -w -X github.com/zhenghaoz/gorse/cmd/version.Version$(git describe --tags $(git rev-parse HEAD)) -X github.com/zhengh…

如何在強數據一致性要求下設計數據庫的高可用架構

在高可用的三大架構設計(基于數據層的高可用、基于業務層的高可用,以及融合的高可用架構設計)中。僅僅解決了業務連續性的問題:也就是當服務器因為各種原因,發生宕機,導致MySQL 數據庫不可用之后,快速恢復業務。但對有狀態的數據庫服務來說,在一些核心業務系統中,比如…

運營商卷大模型,云廠商霸主地位不保?

文&#xff5c;藝 思 編&#xff5c;王一粟 經過了2023年的小試牛刀&#xff0c;2024年&#xff0c;三大運營商帶著大模型一路狂飆。 剛剛過去的5月&#xff0c;中國電信、中國移動、中國聯通三大運營商集體完成了新一輪的大模型進化&#xff0c;特別是圍繞大模型的研發與…

【區分vue2和vue3下的element UI TimePicker 時間選擇器組件,分別詳細介紹屬性,事件,方法如何使用,并舉例】

在 Vue 2 中&#xff0c;我們通常使用 Element UI 來實現時間選擇器&#xff08;TimePicker&#xff09;組件。然而&#xff0c;在 Vue 3 中&#xff0c;Element UI 沒有官方支持 Vue 3 的版本。但是&#xff0c;有一個名為 Element Plus 的庫&#xff0c;它是 Element UI 的 V…

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;實現生產過程的實時監測、模擬與優化&#…

垃圾回收算法

垃圾回收基于“對象不再使用”的原則&#xff0c;自動檢測并回收不再被引用的對象。JVM通過跟蹤對象的引用關系來判斷對象是否仍在使用中。當一個對象沒有任何引用指向它時&#xff0c;垃圾回收器就會將其標記為可回收對象。 垃圾回收的工作機制 標記-清除&#xff08;Mark-S…

ros與硬件的交互

&#xff08;一&#xff09; 與usb相機的交互 第一個鏈接是 先從usb中拿到圖像&#xff0c;然后再發布和訂閱 【C】ROS&#xff1a;cv_bridge包使用與圖像轉換示例_cvbridge-CSDN博客 第二個鏈接是使用方法 ROS學習筆記--cv_bridge_cvbridge-CSDN博客 第三個鏈接是&#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…

2024.6.05總結1102

今天刷到一個視頻&#xff0c;話題非常沉重&#xff0c;看完后感覺整個人特別壓抑。 這個話題是&#xff1a;“高考能改變一個人的命運嗎&#xff1f;”在這個視頻中&#xff0c;主持人采訪了很多個人&#xff0c;但很多人的觀點是今時不同往日&#xff0c;想要靠高考改變命運很…

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;讓你的文檔…

充電樁軟硬件,賺錢新招數!-慧哥充電樁開源系統

慧哥充電樁開源平臺V2.5.2_----- SpringCloud 汽車 電動自行車 云快充1.5、云快充1.6 https://liwenhui.blog.csdn.net/article/details/134773779?spm1001.2014.3001.5502 充電樁軟件和硬件一體化的盈利方向可以清晰地歸納為以下幾個主要方面&#xff1a; 充電服務收費&…