亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python OpenCV實戰(zhàn)之與機器學習的碰撞

 更新時間:2021年12月03日 11:55:51   作者:盼小輝丶  
機器學習是人工智能的子集,為計算機以及其它具有計算能力的系統(tǒng)提供自動預測或決策的能力。本文主要介紹了OpenCV 提供的常見機器學習算法和技術,用于解決計算機視覺項目中的實際問題,需要的朋友可以參考一下

0. 前言

機器學習是人工智能的子集,它為計算機以及其它具有計算能力的系統(tǒng)提供自動預測或決策的能力,諸如虛擬助理、車牌識別系統(tǒng)、智能推薦系統(tǒng)等機器學習應用程序給我們的日常生活帶來了便捷的體驗。機器學習的蓬勃發(fā)展,得益于以下三個關鍵因素:1) 海量數(shù)據集;2) 算法的快速發(fā)展;3) 計算機硬件的發(fā)展。在本文中,我們將學習 OpenCV 提供的常見機器學習算法和技術,用于解決計算機視覺項目中的實際問題,例如分類和回歸問題。

1. 機器學習簡介

機器學習是利用計算機編程,從歷史數(shù)據中學習以對新數(shù)據進行預測的過程。機器學習可以分為三類——監(jiān)督學習、無監(jiān)督學習和半監(jiān)督學習,這些技術所包含的算法如下圖所示:

1.1 監(jiān)督學習

監(jiān)督學習使用的樣本都有相應的期望輸出值(或稱為樣本標簽),由于我們知道每個訓練數(shù)據的正確標簽,因此監(jiān)督學習可以根據預測與相應的期望輸出之間的差異來校正這些預測?;谶@些校準,算法可以從錯誤中學習以調整其內部參數(shù),以擬合出最接近樣本集合與相應的期望輸出之間的函數(shù)。

監(jiān)督學習問題可以進一步分為以下分類和回歸:

  1. 分類:當輸出變量是類別時,可以認為該問題是分類問題。在分類問題中,算法將輸入映射到輸出標簽。
  2. 回歸:當輸出變量為實數(shù)時,在回歸問題中,算法將輸入映射到連續(xù)的實數(shù)輸出。

在監(jiān)督學習中,主要需要考慮以下問題:

偏差-方差的權衡 (Bias-variance trade-off):模型對數(shù)據欠擬合的模型具有高偏差,而對數(shù)據過擬合的模型具有高方差:

偏差是由于學習算法中的錯誤假設而產生的誤差,可以定義為模型的預測與期望的正確值之間的差異。具有高偏差的模型無法找到數(shù)據中的所有模式(欠擬合),因此它不能很好地擬合訓練集,也不會很好地擬合測試集。

方差定義為算法學習錯誤事物的傾向,其會同時擬合數(shù)據中的真實信號以及噪聲。因此,具有高方差的模型(過擬合)非常適合訓練集,但無法泛化到測試集,因為它學習了數(shù)據中的噪聲。

模型復雜度和訓練數(shù)據量:模型復雜度是指機器學習算法試圖的復雜度。模型的復雜度通常由訓練數(shù)據決定:例如,如果使用少量數(shù)據來訓練模型,那么低復雜度的模型更可取,這是因為高復雜度的模型會導致過擬合。

輸入空間的維度:在處理高維空間數(shù)據時,學習可能非常困難,因為會有許多額外的特征會混淆學習過程,也稱為維度災難。因此,在處理高維空間數(shù)據時,常見的方法是修改學習算法,使其具有高偏差和低方差。

1.2 無監(jiān)督學習

在無監(jiān)督學習中,樣本集合缺少每個樣本對應的輸出值(樣本集合沒有被標記、分類或歸類)。無監(jiān)督學習的目標是對樣本集合中的結構或分布進行建模和推斷。因此,在無監(jiān)督學習中,算法利用數(shù)據中進行推斷,并試圖揭示其中的隱藏分布信息。聚類和降維是無監(jiān)督學習中最常用的兩種算法。

1.3 半監(jiān)督學習

半監(jiān)督學習可以看作是監(jiān)督學習和無監(jiān)督學習之間的折衷,因為它同時使用標記和未標記的數(shù)據進行訓練。許多現(xiàn)實世界的機器學習問題可以歸類為半監(jiān)督,因為正確標記所有數(shù)據可能非常困難或耗時,而未標記的數(shù)據更容易收集。

2. K均值 (K-Means) 聚類

OpenCV 提供了 cv2.kmeans() 函數(shù)實現(xiàn) K-Means 聚類算法,該算法找到簇的中心并將輸入樣本分組到簇周圍。

K-Means 聚類算法的目標是將 n 個樣本劃分(聚類)為 K 個簇,其中每個樣本都屬于具有最近均值的簇,cv2.kmeans() 函數(shù)用法如下:

retval, bestLabels, centers=cv.kmeans(data, K, bestLabels, criteria, attempts, flags[, centers])

data 表示用于聚類的輸入數(shù)據,它是 np.float32 數(shù)據類型,每一列包含一個特征;K 指定最后需要的簇數(shù);算法終止標準由 criteria 參數(shù)指定,該參數(shù)設置最大迭代次數(shù)或所需精度,當滿足這些標準時,算法終止。criteria 是具有三個參數(shù) (type, max_item, epsilon) 的元組:

criteria 參數(shù)的標準示例如下:

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)

上述語句表示,最大迭代次數(shù)設置為 20 (max_iterm = 20),所需精度為 1.0 (epsilon = 1.0)。

attempts 參數(shù)指定使用不同的初始標簽執(zhí)行算法的次數(shù)。flags 參數(shù)指定初始化簇中心的方法,其可選值包括:cv2.KMEANS_RANDOM_CENTERS 每次選擇隨機初始化簇中心;cv2.KMEANS_PP_CENTERS 使用 Arthur 等人提出的 K-Means++ 中心初始化。

cv2.kmeans() 返回以下內容:

返回值 解釋
bestLabels 整數(shù)數(shù)組,用于存儲每個樣本的簇索引
center 包含每個簇中心的數(shù)組
compactness 每個點到其簇中心的距離平方和

2.1 K-Means 聚類示例

作為示例,我們將使用 K-Means 聚類算法對一組 2D 點進行聚類。這組 2D 點由 240 個點組成,使用兩個特征進行了描述:

# 2D數(shù)據
data = np.float32(np.vstack((np.random.randint(0, 50, (80, 2)), np.random.randint(40, 90, (80, 2)), np.random.randint(70, 110, (80, 2)))))
# 可視化
plt.scatter(data[:, 0], data[:, 1], c='c')
plt.show()

如上圖所示,數(shù)據將作為聚類算法的輸入,每個數(shù)據點有兩個特征對應于 (x, y) 坐標,例如,這些坐標可以表示 240 人人的身高和體重,而 K-Means 聚類算法用于決定衣服的尺寸(例如 K=3,則相應表示尺寸為 S、M 或 L)。

接下來,我們將數(shù)據劃分為 2 個簇。第一步是定義算法終止標準,將最大迭代次數(shù)設置為 20 (max_iterm = 20),epsilon 設置為 1.0 (epsilon = 1.0):

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)

然后調用 cv2.kmeans() 函數(shù)應用 K-Means 算法:

ret, label, center = cv2.kmeans(data, 2, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

由于返回值 label 存儲每個樣本的聚類索引,因此,我們可以根據 label 將數(shù)據拆分為不同的集群:

A = data[label.ravel() == 0]
B = data[label.ravel() == 1]

最后繪制 A 和 B 以及聚類前后的數(shù)據,以便更好地理解聚類過程:

fig = plt.figure(figsize=(12, 6))
plt.suptitle("K-means clustering algorithm", fontsize=14,
fontweight='bold')
# 繪制原始數(shù)據
ax = plt.subplot(1, 2, 1)
plt.scatter(data[:, 0], data[:, 1], c='c')
plt.title("data")
# 繪制聚類后的數(shù)據和簇中心
ax = plt.subplot(1, 2, 2)
plt.scatter(A[:, 0], A[:, 1], c='b')
plt.scatter(B[:, 0], B[:, 1], c='g')
plt.scatter(center[:, 0], center[:, 1], s=100, c='m', marker='s')
plt.title("clustered data and centroids (K = 2)")
plt.show()

接下來,我們修改參數(shù) K 進行聚類并進行相應的可視化。例如需要將數(shù)據分為三個簇,則首先應用相同的過程對數(shù)據進行聚類,只需要修改參數(shù) (K=3) 將數(shù)據分為 3 個簇:

ret, label, center = cv2.kmeans(data, 3, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

然后,當使用標簽輸出分離數(shù)據時,將數(shù)據分為三組:

A = data[label.ravel() == 0]
B = data[label.ravel() == 1]
C = data[label.ravel() == 2]

最后一步是顯示 A 、 B 和 C ,以及簇中心和訓練數(shù)據:

fig = plt.figure(figsize=(12, 6))
plt.suptitle("K-means clustering algorithm", fontsize=14,
fontweight='bold')
# 繪制原始數(shù)據
ax = plt.subplot(1, 2, 1)
plt.scatter(data[:, 0], data[:, 1], c='c')
plt.title("data")
# 繪制聚類后的數(shù)據和簇中心
ax = plt.subplot(1, 2, 2)
plt.scatter(A[:, 0], A[:, 1], c='b')
plt.scatter(B[:, 0], B[:, 1], c='g')
plt.scatter(C[:, 0], C[:, 1], c='r')
plt.scatter(center[:, 0], center[:, 1], s=100, c='m', marker='s')
plt.title("clustered data and centroids (K = 3)")
plt.show()

我們也可以將簇數(shù)設置為 4,觀察算法運行結果:

ret, label, center = cv2.kmeans(data, 4, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

3. K最近鄰

k-最近鄰 (k-nearest neighbours, kNN) 是監(jiān)督學習中最簡單的算法之一,kNN 可用于分類和回歸問題。在訓練階段,kNN 存儲所有訓練樣本的特征向量和類別標簽。在測試階段,將未標記的向量分類為距離最近的 k 個訓練樣本中出現(xiàn)頻率最高的類標簽,其中 k 是用戶定義的常數(shù):

如上圖所示,如果 k = 5,則綠色圓圈(未標記的測試樣本)將被歸類為三角形,因為離其最近的 5 個樣本中有 3 個三角形但只有 1 個菱形;如果 k = 9,則綠色圓圈將被歸類為菱形,因為離其最近的 9 個樣本中有 5 個菱形但只有 4 個三角形。

在 OpenCV 中,使用 kNN 分類器首先需要使用 cv2.ml.KNearest_create() 創(chuàng)建 kNN 分類器,然后提供數(shù)據和標簽以使用 train() 方法訓練 kNN分類器。最后,使用 findNearest() 方法用于查找測試樣本鄰居,使用如下:

retval, results, neighborResponses, dist=cv2.ml_KNearest.findNearest(samples, k[, results[, neighborResponses[, dist]]])

其中,samples 是輸入樣本,k 設置為最近鄰居的個數(shù),results 存儲每個輸入樣本的預測值,neighborResponses 存儲對應的鄰居,dist 存儲輸入樣本到相應鄰居的距離。

3.1 K最近鄰示例

接下來,為了演示 kNN 算法,首先隨機創(chuàng)建一組點并分配一個標簽 (0 或 1)。標簽 0 將代表紅色三角形,而標簽 1 將代表藍色方塊;然后,使用 kNN 算法根據 k 個最近鄰對樣本點進行分類。

第一步是創(chuàng)建具有相應標簽的點集和要分類的樣本點:

# 點集由50個點組成
data = np.random.randint(0, 100, (50, 2)).astype(np.float32)
# 為1每個點創(chuàng)建標簽 (0:紅色, 1:藍色)
labels = np.random.randint(0, 2, (50, 1)).astype(np.float32)
# 創(chuàng)建要分類的樣本點
sample = np.random.randint(0, 100, (1, 2)).astype(np.float32)

接下來,創(chuàng)建 kNN 分類器,訓練分類器,并找到要分類樣本點的 k 個最近鄰居:

# 創(chuàng)建 kNN 分類器
knn = cv2.ml.KNearest_create()
# 訓練 kNN 分類器
knn.train(data, cv2.ml.ROW_SAMPLE, labels)
# 找到要分類樣本點的 k 個最近鄰居
k = 3
ret, results, neighbours, dist = knn.findNearest(sample, k)
# 打印結果
print("result: {}".format(results))
print("neighbours: {}".format(neighbours))
print("distance: {}".format(dist))

# 可視化
fig = plt.figure(figsize=(8, 6))
red_triangles = data[labels.ravel() == 0]
plt.scatter(red_triangles[:, 0], red_triangles[:, 1], 200, 'r', '^')
blue_squares = data[labels.ravel() == 1]
plt.scatter(blue_squares[:, 0], blue_squares[:, 1], 200, 'b', 's')
plt.scatter(sample[:, 0], sample[:, 1], 200, 'g', 'o')
plt.show()

獲得結果如下所示:

result: [[0.]]

neighbours: [[0. 0. 1.]]

distance: [[13. 40. 65.]]

因此,綠點被歸類為紅色三角形,可視化效果如下所示:

4. 支持向量機

支持向量機 (Support Vector Machine, SVM) 是一種監(jiān)督學習技術,它通過根據指定的類對訓練數(shù)據進行最佳分離,從而在高維空間中構建一個或一組超平面。

已二維平面為例,在下圖中看到,其中綠線是能夠將兩個類分開的最佳超平面,因為其到兩個類中的最近元素的距離是最大的:

上圖第一種情況下,決策邊界是一條線,而在第二種情況下,決策邊界是一條圓形曲線,虛線代表其他決策邊界,但它們并非最好地將兩個類分開的決策邊界。

OpenCV 中的 SVM 實現(xiàn)基于 LIBSVM,使用 cv2.ml.SVM_create() 函數(shù)創(chuàng)建空模型,然后為模型分配主要參數(shù):

svmType :設置 SVM 類型,可選值如下:

  • SVM_C_SVC:C CC-支持向量分類,可用于 n 分類 (n≥2) 問題
  • NU_SVC: v vv-支持向量分類
  • ONE_CLASS: 分布估計(單類 SVM)
  • EPS_SVR: ? \epsilon?-支持向量回歸
  • NU_SVR: v vv-支持向量回歸

kernelType :這設置了 SVM 的核類型,可選值如下:

  • LINEAR : 線性核
  • POLY :多項式核
  • RBF : Radial Basis Function (RBF),大多數(shù)情況下是不錯的選擇
  • SIGMOID : Sigmoid 核
  • CHI2 : 指數(shù) Chi2 核,類似于 RBF 核
  • INTER : 直方圖交集核;運行速度較快的核

degree : 核函數(shù)的 degree 參數(shù) (用于 POLY 核)

gamma :核函數(shù)的 γ \gammaγ 參數(shù)(用于 POLY/RBF/SIGMOID/CHI2 核)

coef0 : 核函數(shù)的 coef0 參數(shù) (用于 POLY/SIGMOID 核)

Cvalue : SVM 優(yōu)化問題的 C 參數(shù) (用于 C_SVC/EPS_SVR/NU_SVR 類型)

nu : SVM 優(yōu)化問題的 v vv 參數(shù) (用于 NU_SVC/ONE_CLASS/NU_SVR 類型)

p : SVM 優(yōu)化問題的 ? \epsilon? 參數(shù) (用于 EPS_SVR 類型)

classWeights : C_SVC 問題中的可選權重,分配給特定的類

termCrit :迭代 SVM 訓練過程的終止標準

核函數(shù)選擇通常取決于數(shù)據集,通??梢允紫仁褂?RBF 核進行測試,因為該核將樣本非線性地映射到更高維空間,可以方便的處理類標簽和屬性之間的關系是非線性的情況。

默認構造函數(shù)使用以下值初始化 SVM:

svmType: C_SVC, kernelType: RBF, degree: 0, gamma: 1, coef0: 0, C: 1, nu: 0, p: 0, classWeights: 0, termCrit: TermCriteria(MAX_ITER+EPS, 1000, FLT_EPSILON )

4.1 支持向量機示例

為了解如何在 OpenCV 中使用 SVM,首先需要創(chuàng)建訓練數(shù)據和標簽:

labels = np.array([1, 1, -1, -1, -1])
data = np.matrix([[800, 40], [850, 400], [500, 10], [550, 300], [450, 600]], dtype=np.float32)

以上代碼創(chuàng)建了 5 個點,前 2 個點被指定為 1 類,而另外 3 個被指定為 -1 類。接下來使用 svm_init() 函數(shù)初始化 SVM 模型:

def svm_init(C=12.5, gamma=0.50625):
    """ 創(chuàng)建 SVM 模型并為其分配主要參數(shù),返回模型 """
    model = cv2.ml.SVM_create()
    model.setGamma(gamma)
    model.setC(C)
    model.setKernel(cv2.ml.SVM_LINEAR)
    model.setType(cv2.ml.SVM_C_SVC)
    model.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6))
    return model
# 初始化 SVM 模型
svm_model = svm_init(C=12.5, gamma=0.50625)

創(chuàng)建的 SVM 核類型設置為 LINEAR,SVM 的類型設置為 C_SVC。

然后,編寫 svm_train() 函數(shù)訓練 SVM 模型:

def svm_train(model, samples, responses):
    # 使用 samples 和 responses 訓練模型
    model.train(samples, cv2.ml.ROW_SAMPLE, responses)
    return model
# 訓練 SVM
svm_train(svm_model, data, labels)

然后創(chuàng)建一個圖像,并繪制 SVM 響應:

def show_svm_response(model, image):

    colors = {1: (255, 255, 0), -1: (0, 255, 255)}

    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            sample = np.matrix([[j, i]], dtype=np.float32)
            response = svm_predict(model, sample)

            image[i, j] = colors[response.item(0)]
    
    cv2.circle(image, (800, 40), 10, (255, 0, 0), -1)
    cv2.circle(image, (850, 400), 10, (255, 0, 0), -1)

    cv2.circle(image, (500, 10), 10, (0, 255, 0), -1)
    cv2.circle(image, (550, 300), 10, (0, 255, 0), -1)
    cv2.circle(image, (450, 600), 10, (0, 255, 0), -1)

    support_vectors = model.getUncompressedSupportVectors()
    for i in range(support_vectors.shape[0]):
        cv2.circle(image, (support_vectors[i, 0], support_vectors[i, 1]), 15, (0, 0, 255), 6)
# 創(chuàng)建圖像
img_output = np.zeros((640, 1200, 3), dtype="uint8")
# 顯示 SVM 響應
show_svm_response(svm_model, img_output)

如上圖所示,SVM 使用訓練數(shù)據進行了訓練,可用于對圖像中所有點進行分類。SVM 將圖像劃分為黃色和青色區(qū)域,可以看到兩個區(qū)域之間的邊界對應于兩個類之間的最佳間隔,因為到兩個類中最近元素的距離最大,支持向量用紅線邊框顯示。

小結

在本文中,首先介紹機器學習的概念及其相關話題,然后總結了機器學習中的三種主要方法,并總結了分類、回歸和聚類問題的三種最常見的技術。最后,我們通過示例了解了常用機器學習算法,具體而言,包括 K-Means 聚類算法、kNN 算法和 SVM 算法。?

以上就是Python OpenCV實戰(zhàn)之與機器學習的碰撞的詳細內容,更多關于OpenCV 機器學習的資料請關注腳本之家其它相關文章!

相關文章

最新評論