背景
問題陳述
目標
範圍
載入和準備圖像
影像格式化和轉換
特徵提取和選擇
邏輯迴歸
線性判別分析
K 最近鄰
決策樹
隨機森林
樸素貝葉斯
支援向量機
準確性和性能指標
機器學習模型的比較
限制和挑戰
成果總結
貢獻及意義
未來的工作和改進
植物病害對農業生產力構成重大威脅,導致產量損失和農民的經濟困難。及時且準確地檢測植物病害對於實施有效的病害管理策略和最大限度地減少作物損失至關重要。傳統的手動疾病診斷方法耗時、主觀且容易出錯。因此,機器學習和影像處理等技術的整合已成為自動化和增強植物病害檢測的一種有前途的方法
該計畫的主要目標是利用機器學習演算法和影像處理技術開發植物病害檢測系統。透過自動化檢測過程,農民和農業專家可以及時識別和解決植物病害,從而能夠及時幹預並優化作物管理實踐
該專案的主要目標如下
開發強大且準確的植物病害檢測系統
實施機器學習演算法對植物葉子進行自動分類
利用影像處理技術從葉子影像中提取相關特徵
評估不同機器學習模型的性能和準確性
提供使用者友善的介面,方便直觀地與系統交互
該計畫的重點是檢測植物病害,特別是蘋果葉中的病害。用於訓練和測試模型的資料集來自 Plant-Village 資料集,其中包含健康蘋果葉子和受蘋果黑星病、黑腐病和雪松蘋果銹病等疾病影響的葉子的圖像。分類,為農民和農業專業人員有效識別和管理植物病害提供實用工具。該項目不涉及現場實時疾病檢測或圖像採集的硬體設備集成
用於此植物病害檢測系統的資料集包括從植物村資料集中獲得的蘋果葉影像。此資料集分為四個主要類別,代表不同類別的蘋果葉狀況 Apple___Apple_scab、Apple___Black_rot、Apple___Cedar_apple_rust 和 Apple___healthy
Apple___Apple_scab:此類別包含 630 張圖像,其中 598 張圖像用於訓練,32 張圖像用於測試
Apple___Black_rot:此資料集包含該類別中的 621 張圖像,其中 589 張圖像分配用於訓練,32 張圖像用於測試
Apple___Cedar_apple_rust:此資料集由 275 張受雪松蘋果銹病影響的葉子圖像組成,其中 261 張圖像用於訓練,14 張圖像用於測試
Apple___healthy:此類別包含 1645 張健康蘋果葉的圖像。其中,1562 張圖像指定用於訓練,83 張圖像保留用於測試。
訓練圖像用於教導機器學習模型識別模式並區分健康和患病的葉子。測試圖像用於評估經過訓練的模型在未見過的數據上的性能和準確性通過利用這個多樣化的數據集,植物病害檢測系統旨在準確地將蘋果葉分類為健康或受蘋果黑星病、黑腐病或蘋果病等疾病影響。此資料集的組成使系統能夠從各種葉子狀況中學習,並提高其準確概括和識別植物疾病的能力
載入和準備圖像
在蘋果葉病檢測計畫中,第一步是取得由不同疾病影響的蘋果葉影像組成的資料集。然後將這些圖像載入到系統中,以便可以進行進一步處理。此外,透過執行必要的調整來準備圖像,例如將其大小調整為一致的分辨率、裁剪掉不必要的部分或標準化顏色分佈圖像格式和轉換一旦加載蘋果葉圖像,就需要對它們進行格式化和轉換,以確保與專案後續階段的兼容性。這涉及透過將影像格式轉換為特定的檔案類型(如 JPEG 或 PNG)來標準化影像格式。此外,可以對色彩空間解析度或其他影像屬性進行調整,以確保一致性並促進準確分析
特徵提取和選擇
特徵提取是檢測蘋果葉片病害的關鍵步驟。使用各種技術從葉子圖像中提取相關特徵。這些技術包括分析紋理以捕捉與疾病相關的紋理圖案,檢查顏色以識別與特定疾病相關的變化,以及研究形狀以檢測葉子形態的不規則性。透過提取這些獨特的特徵,後續的機器學習演算法可以有效區分健康和患病的蘋果葉子
特徵選擇
此步驟涉及根據提取的特徵的相關性和辨別力來選擇提取的特徵的子集。特徵選擇透過消除雜訊或冗餘資訊來幫助降低資料集的維數。透過選擇資訊量最大的特徵,可以提高疾病檢測模型的效率和準確性
蘋果葉病檢測計畫利用一系列機器學習演算法來開發有效的疾病分類模型。採用以下演算法
邏輯回歸:邏輯回歸用於根據提取的特徵來預測蘋果葉健康或患病的機率
線性判別分析:線性判別分析透過找到最能區分健康和患病樣本的特徵線性組合來幫助對蘋果葉進行分類
K 最近鄰 (KNN):K 最近鄰透過將蘋果葉子的特徵與特徵空間中最近鄰居的特徵進行比較來對蘋果葉子進行分類
決策樹:決策樹使用一系列 if-else 條件根據樣本的特徵及其層次關係對樣本進行分類
隨機森林:隨機森林是一種整合學習方法,結合多個決策樹來增強分類精確度
樸素貝葉斯:樸素貝葉斯是一種機率演算法,用於計算蘋果葉屬於特定疾病類別的機率
支援向量機(SVM):支援向量機在高維度特徵空間中建構超平面來對蘋果葉子進行分類
選擇機器學習演算法後,使用由帶有相應疾病標籤的蘋果葉圖像組成的標記資料集來訓練模型。模型在訓練階段學習辨識特徵和疾病類別之間的模式和關係。使用訓練期間未使用的單獨驗證資料集對訓練後的模型進行評估。這有助於評估模型準確分類看不見的蘋果葉樣本的能力
一旦模型經過訓練和驗證,就會在包含新的、看不見的蘋果葉圖像的單獨測試資料集上進行測試。模型預測每個樣本的疾病類別,並計算準確率、精確率、召回率和F1分數等表現評估指標,以衡量模型在疾病檢測方面的有效性
在[1]中:
# -----------------------------------# 全域特徵提取# --------- --------------------------from sklearn.preprocessing import LabelEncoderfrom sklearn.preprocessing import MinMaxScalerimport numpy as npimport mahotasimport cvimport osimport h5py# ----- ---------------# 可調參數# ------------------------------ --images_per_class = 800fixed_size = tuple(( 500 , 500 ))train_path =“../dataset/train”test_path =“../dataset/test”h5_train_features =“../embeddings/features/hatures.labs5” “../embeddings/labels/labels.h5” bins = 8##### BGR To RGB ConversionIn [2]:# 將每個影像從BGR format 轉換為RGBdef rgb_bgr(image):rgb_img = cv2.cvtColor( 。 .COLOR_RGB2HSV)return hsv_img##### Image SegmentationIn [4]: # 提取綠色和棕色colordef img_segmentation(rgb_img, hsv_img):lower_green = np.array([ 25 , 0 , 20m):low; 100 , 255 , 255 ])healthy_mask = cv2.inRange(hsv_img , lower_green, upper_green)結果= cv2.bitwise_and(rgb_img, rgb_img, mask=healthy_mown), 0. np .array([ 30 , 255 , 255 ])disease_mask = cv2 .inRange(hsv_img, lower_brown, upper_brown)disease_result = cv2.bitwise_and(rgb_img, rgb_img, mask cv2.bitwise_and(rgb_img, rgb_img , mask=final_mask)return Final_result##### 確定特徵描述子###### 1. Hu MomentsIn [5]:# feature-descriptor-1: Hu Momentsdef fd_hu_moments(image):image = cv2.cvtColor( image, cv2.COLOR_BGR2GRAY)feature = cv2.HuMoments(cv2. moment(image)).flatten()return feature###### 2.HaralickTexturesIn [6]:# feature-descriptor-2: HaralickTexture flick :gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY )haralick = mahotas.features.haralick(gray).mean(axis= 0 )return haralick###### 3. 顏色直方圖In [7]:# feature -descriptor-3: 顏色直方圖def fd_histogram(image, mask=None ):圖片 = cv2.cvtColor(圖片, cv2.COLOR_BGR2HSV)hist = cv2.calcHist( [圖],[ 0 , 1 , 2 ],無,[箱,箱,箱],[ 0 , 256 , 0 , 256 , 0 ,256 ] )cv2.normalize(hist, hist)return hist.flatten()######載入訓練資料集In [8]:# 取得訓練標籤train_labels = os.listdir(train_path)# 對訓練標籤進行排序train_labels. sort() print(train_labels)# 保存特徵向量和標籤的空列表global_features = []labels = [] ['Apple___Apple_scab', 'Apple___Black_rot', 'Apple___Cedar_apple_rust','Apple___healthy']###### 從資料集中產生特徵和標籤嵌入[9]:# 循環遍歷訓練資料子資料夾fortrain_labels中的training_name:# join訓練資料路徑和每個物種訓練資料夾img_dir_path = os.path.join(train_path,training_name)#取得目前訓練標籤current_label =training_name#循環遍歷每個子資料夾中的圖片for img in os.listdir(img_dir_path): #取得影像檔案名稱file = os.path.join(img_dir_path, img)#讀取映像並將其大小調整為固定大小image = cv2.imread(file)image = cv2.resize(image,fixed_size)#執行函數Bit By BitRGB_BGR = rgb_bgr(image)BGR_HSV = bgr_hsv(RGB_BGR)IMG_SEGMENT = img_segmentation(RGB_BGR, BGR_HSV)# 呼叫全域特徵描述元histogram(IMG_SEGMENT) )# 連線全域特徵global_feature = np.hstack( [fv_histogram, fv_haralick,fv_hu_moments])# 更新標籤和特徵向量列表labels.append(current_label)global_features.append(global_feature)print("[STATUS] 已處理資料夾 {}". (current_label))print("[狀態]已完成全域特徵提取...」) [STATUS] 已處理的資料夾:Apple___Apple_scab[STATUS] 已處理的資料夾:Apple___Black_rot[STATUS] 已處理的資料夾:Apple___Cedar_apple_rust[STATUS] 已處理的資料夾:Apple___healthy[STATUS] 已完成全域特徵提取.. .在[10]:# print(global_features)In [ 41]:# 取得整體特徵向量sizeprint("[STATUS]特徵向量size{}".format(np.array(global_features).shape)) [STATUS]特徵向量大小(3010, 532)在[12]中:#取得整體訓練標籤大小# print(labels)print("[STATUS]訓練標籤{}".format(np.array(labels).shape )) [狀態] 訓練標籤 (3010,)
標籤編碼值Apple___Apple_scab 0Apple___Black_rot 1Apple___Cedar_apple_rust 2Apple___healthy 3
在[13]中:
targetNames = np.unique(labels) le = LabelEncoder() target = le.fit_transform(labels) print(targetNames) print("[STATUS] 訓練標籤已編碼...") ['Apple___Applerab'Apple '_______rot' 'Apple___ ' Apple___healthy'] [狀態] 訓練標籤編碼...
在[14]中:
from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=( 0 , 1 ))rescaled_features = scaler.fit_transform(global_features)print("[STATUS] 特徵向量歸一化...")rescaled_features[STATUS] 特徵向量歸一化...")rescaled_atures[STATUS] ...輸出[14]:數組([[0.8974175,0.03450962,0.01845123,...,0.02027887,0.12693291,0.96573218], [0.89815922, 0.13025558, 0.02774864, ..., 0.02027767, 0.12692423,0.96573354], [0.56777027, 0., 0.01540143, ..., 0.02027886, 0.12693269,0.96573218], ..., [0.95697685, 0.01228793, 0.00548476, ..., 0.02027886, 0.12693346,0.96573218], [0.97704002, 0.10614054, 0.03136325, ..., 0.02027885, 0.12692424,0.96573217], [0.95214074, 0.03819411, 0.03671892, ..., 0.02027886, 0.12692996,0.96573217]])print("[STATUS] 目標標籤:{}".Fformat}" .format(目標.形狀)) [狀態]目標標籤:[0 0 0 ... 3 3 3] [狀態]目標標籤形狀:(3010,)
一個。特徵
h5f_data = h5py.File(h5_train_features, "w")h5f_data.create_dataset("dataset_1", data=np.array(rescaled_features))Out[16]:<HDF5 資料集"dataset_1": 形狀(3010, 532) 類型" <f8>
h5f_label = h5py.File(h5_train_labels, "w")h5f_label.create_dataset("dataset_1", data=np.array(target))Out[17]:<HDF5 資料集"dataset_1": 形狀(3010,), 類型" < i8">在[43]:h5f_data.close()h5f_label.close()
# -----------------------------------# 訓練我們的模型# -------- - --------------------------導入h5py 導入numpy 以np 導入資料導入cv 導入警告from matplotlib 導入pyplotfrom sklearn.model_selection 導入train_test_split, cross_val_scorefrom sklearn.model_selection 導入KFold,分層KFoldfrom sklearn.metrics 導入confusion_matrix、accuracy_score、classification_reportfrom sklearn.linear_model 你導入Logonecteralcom 母帶導入卷書。 Classifierfrom sklearn.neighbors 導入KNeighborsClassifierfrom sklearn.discriminant_analysis 導入LinearDiscriminantAnalysisfrom sklearn.na ive_bayes導入GaussianNBfrom sklearn.svm 導入SVC 導入joblibwarnings.filterwarnings("忽略")# --------------------# 可調參數# -------- ------------num_trees = 100test_size = 0.seed = 9scoring = "accuracy"# 取得訓練標籤train_labels = os.listdir(train_path)# 對訓練標籤進行排序train_labels.sort()if not os.path.exists(test_path):os.makedirs(test_path) # 建立所有機器學習模型models = []models.append(("LR", LogisticRegression(random_state=seed)))models.append(("LDA" , LinearDiscriminantAnalysis()))models.append(("KNN", KNeighborsClassifier()))models.append(("DTC", DecisionTreeClassifier(random_state=seed))))).append(("RFels., RandomForestClassif num_trees,random_state=seed)))models.append(("NB ", GaussianNB()))models.append(("SVM", SVC(random_state=seed)))# 儲存結果和名稱的變數results = [] names = []# 導入特徵向量和訓練好的標籤sh5f_data = h5py.檔案(h5_train_features,「r」)h5f_label = h5py.File(h5_train_labels,「r」)global_features_string = h5f_train_labels,「r」)global_features_string = h5f_data[“dataset_1”] dataset_1”]global_features = np.array(global_features_string)global_labels = np.array( global_labels_string)h5f_data.close()h5f_label.close()#驗證特徵向量和標籤的形狀 (cature:STATUS] shfe}" format(global_features.shape))print("[STATUS] labels shape: {}".format(global_labels.shape))print("[STATUS] 訓練開始...")print(global_labels, len(global_labels), len (global_features)) [狀態]特徵形狀:(3010, 532) [狀態]標籤形狀:(3010,) [狀態] 訓練開始... [0 0 0 ... 3 3 3] 3010 3010
在[38]中:
(trainDataGlobal、testDataGlobal、trainLabelsGlobal、testLabelsGlobal、 ) = train_test_split(np.array(global_features), np.array(global_labels),test_size=test_size, random_state=seed)print("[STATUS] 分割訓練與測試資料...")print("訓練資料:{} ".format(trainDataGlobal.shape))print("測試資料:{}".format(testDataGlobal.shape)) [狀態] 分割訓練與測試資料...訓練資料:(2408, 532)測試資料:(602, 532)In [40]:trainDataGlobalOut[40]:array([[9.47066972e-01, 1.97577832e-02 ,5.34481987e-04,...,2.02788613e-02,1.26936845e-01,9.65732178e-01], [9.67673181e-01、4.20456024e-02、5.76285634e-02、...、2.02788294e-02、1.26933581e-01、9.65732217e-01], [9.84705756e-01、2.97800312e-02、1.34500344e-02、...、2.02788553e-02、1.26941878e-01、9.65732187e-01], ..., [8.64347882e-01、5.89053245e-02、4.27430333e-02、...、2.02791643e-02、1.26961451e-01、9.65733689e-01], [9.85818416e-01、1.47428536e-03、3.35008392e-03、...、2.02767694e-02、1.26792776e-01、9.65732951e-01], [9.93152188e-01、1.31020292e-03、8.50637768e-04、...、2.02910354e-02、1.27475382e-01、9.65721108e-01])
在[22]中:
對於名稱,模型中的模型:kfold = KFold(n_splits= 10 )cv_results = cross_val_score(model, trainDataGlobal, trainLabelsGlobal, cv=kfold,scoring=scoring)results.append(cv_results)names.app s :%f(%f)“%(名稱,cv_results.mean(),cv_results.std())打印(msg)LR:0.900346(0.020452)LDA:0.892038(0.017931)KNN:0.84978(8497850931)KNN:0.8497820197850199820199782019785. ( 0.014771)RF: 0.967191 (0.012676)NB: 0.839293 (0.014065)SVM: 0.885813 (0.021190)
在[23]中:
Fig = pyplot.figure()fig.suptitle("機器學習演算法比較")ax = Fig.add_subplot( 111 )pyplot.boxplot(results)ax.set_xticklabels(names)pyplot.show()
從上面的結果可以看出,隨機森林分類器模型的準確率最高,為96.7%,高斯NB模型的準確率最低,為83.9%
<div class="highlighthighlight-source-python notranslateposition-relativeoverflow-auto"dir="auto"data-snippet-clipboard-copy-content="在[24]:clf = RandomForestClassifier(n_estimators=num_trees, random_state=種子)在[25]:clf.fit(trainDataGlobal,trainLabelsGlobal)len(trainDataGlobal),len(trainLabelsGlobal)輸出[25]:(2408, 2408)在[34]:y_predict = clf.predict(testDataGlobal) 34]: 陣列([3, 3, 1, 3, 0, 3, 1, 1, 2, 1, 1, 0, 1, 3, 3, 3, 3, 2, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 1, 3, 1, 1, 3, 3, 1, 3, 3, 3, 2, 3, 1, 3, 3, 3, 1, 0, 0, 3, 1, 3, 3, 0, 3, 3, 2, 3, 0, 3, 1, 0, 3, 0, 3, 3, 1, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 2, 1, 1, 2, 0, 2, 1, 1, 0, 0, 3, 2, 0, 3, 2, 3, 3, 2, 3, 3, 1, 1, 3, 2, 0, 2, 1, 1, 2, 3, 3, 3, 1, 1, 0, 3, 0, 3, 3, 0, 3, 3, 3, 1, 2, 3, 2, 3, 0, 3, 0, 3, 1, 3, 3, 3, 3, 3, 2, 1, 0, 1, 3, 3, 3, 1, 3, 3, 0, 0, 3, 3, 3, 0, 2, 3, 3, 0, 1, 1, 3, 0, 0, 3, 1, 3, 3, 1, 3, 2, 1, 0, 0, 3, 0, 1, 0, 1, 0, 1, 2, 3, 3, 3, 3, 3, 2, 1, 1, 3, 3, 1, 3, 1, 3, 2, 1, 3, 3, 0, 3, 0, 3, 3, 3, 1, 1, 3, 2, 3, 0, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 1, 1, 0, 3, 0, 3, 1, 3, 3, 3, 1, 3, 3, 0, 3, 0, 2, 3, 3, 0, 3, 3, 3, 3, 0, 2, 3, 1, 3, 3, 3, 0, 3, 1, 3, 3, 3, 1, 3, 0, 2, 0, 3, 3, 3, 2, 3, 3, 3, 0, 0, 1, 1, 3, 3, 0, 3, 2, 0, 1, 1, 3, 0, 3, 1, 1, 3, 2, 2, 2, 3, 3, 3, 1, 1, 3, 0, 3, 0, 1, 3, 3, 0, 3, 1, 0, 3, 0, 3, 3, 2, 3, 3, 3, 3, 0, 3, 3, 3, 1, 0, 3, 2, 1, 3, 0, 1, 1, 0, 1, 3, 2, 0, 3, 0, 3, 1, 0, 3, 2, 0, 3, 0, 0, 2, 1, 3, 0, 3, 3, 0, 0, 3, 3, 1, 3, 0, 3, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 0, 3, 3, 3, 1, 0, 1, 3, 0, 1, 3, 0, 3, 3, 3, 0, 3, 3, 0, 1, 3, 3, 1, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 1, 0, 3, 3, 0, 3, 3, 1, 0, 3, 1, 1, 3, 3, 3, 2, 3, 0, 0, 3, 3, 3, 3, 3, 3, 2, 1, 3, 3, 0, 3, 0, 1, 3, 1, 3, 3, 1, 1, 1, 1, 3, 3, 3, 1, 3, 0, 3, 3, 3, 2, 3, 1, 3, 3, 1, 1, 3, 3, 3, 0, 0, 3, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 3, 1, 1, 0, 3, 3, 3, 3, 0, 3, 1