互聯(lián)網(wǎng)+智慧農(nóng)業(yè):計(jì)算機(jī)視覺技術(shù)在農(nóng)作物病蟲害檢測方面的應(yīng)用
1 項(xiàng)目簡介
本文引用地址:http://www.ex-cimer.com/article/202204/433328.htm1.1 項(xiàng)目概述
本項(xiàng)目旨在運(yùn)用Python語言分析和闡述計(jì)算機(jī)視覺技術(shù)中的目標(biāo)檢測在農(nóng)作物病蟲害方面的應(yīng)用。具體而言,我們將運(yùn)用Python語言運(yùn)行并得出目標(biāo)葉面中已遭受病蟲害的面積,然后分析是否需要進(jìn)行農(nóng)藥噴灑等防治病蟲害的進(jìn)一步肆虐,進(jìn)而幫助農(nóng)名伯伯更好地管理農(nóng)作物,減少損失、增加產(chǎn)量……
1.2 前期準(zhǔn)備
首先,尋找檢測目標(biāo):這里我們針對一片部分遭受病蟲害的葉片進(jìn)行檢測處理
對葉片分析處理用到python語言及部分第三方庫
在這里:
Python環(huán)境:3.8.2
python編譯器:JetBrains PyCharm 2018.1.2 x64
第三方庫:OpenCV、ilmutils、easygui、numpy、PIL等
2 項(xiàng)目分析
2.1 代碼詳解
導(dǎo)入用到的所有庫
import cv2
import imutils
import easygui
from PIL import Image, ImageDraw, ImageFont
import numpy as np
事先將有病蟲害的葉片部分做畫圖處理(涂成白色) 背景圖
導(dǎo)入圖片并做黑白處理
# foliageNew 作為背景圖,是人為事先在葉子有病蟲害的地方用畫筆涂改為白色的圖片,讀取它
PSpicture = cv2.imread(r"E:foliageNew.png")
# 將圖片 foliageNew 轉(zhuǎn)換為黑白圖像
PSpicture = cv2.cvtColor(PSpicture, cv2.COLOR_BGR2GRAY)
對背景圖再做高斯處理
# 對圖片 foliageNew 進(jìn)行高斯處理
PSpictureGS = cv2.GaussianBlur(PSpicture, (21, 21), 0)
同時(shí)事先將目標(biāo)檢測葉片同樣做畫圖處理(涂成白色)
對其做相同處理
# foliageWhite 是葉子目標(biāo)檢測圖,讀取它
originalPicture = cv2.imread(r"E:foliageWhite.png")
# 將圖片 foliageWhite 轉(zhuǎn)換為黑白圖像
originalPicture = cv2.cvtColor(originalPicture, cv2.COLOR_BGR2GRAY)
# 對圖片 foliageWhite 進(jìn)行高斯處理
originalPictureGS = cv2.GaussianBlur(originalPicture, (21, 21), 0)
對兩張?zhí)幚砗蟮膱D片做差,返回的值代表其差異之處
# 對圖片 foliageNew 和 foliageWhite 做差(對比),返回的結(jié)果代表他們的差異之處
pictureDelta = cv2.absdiff(PSpictureGS, originalPictureGS)
因?yàn)橹笠玫较嚓P(guān)數(shù)據(jù),所以事先查看圖片像素大小
# x, y 是圖片的像素大小
x, y = pictureDelta.shape
print(x, y)
此值與圖片屬性中所示的值相同,這也正是我們期望的結(jié)果
當(dāng)然,這里我們可以做一下邊緣檢測進(jìn)一步確認(rèn)我們想要的檢測目標(biāo)區(qū)域
# pictureDelta 是圖像的區(qū)域,canny 是圖像的輪廓(白色區(qū)域)
img = cv2.GaussianBlur(pictureDelta, (3, 3), 0)
# Canny 邊緣檢測
canny = cv2.Canny(img, 0, 100)
確定目標(biāo)檢測區(qū)域(這里是輪廓區(qū)域,不是整個(gè)圖像區(qū)域)
即在第二次做高斯處理的那個(gè)圖像上確定檢測區(qū)域(像素值為白的區(qū)域就是我們想要的目標(biāo)區(qū)域)
# 畫輪廓,存儲要識別的像素值的位置,記錄在 distinguishLeaf 數(shù)組中
for i in range(x):
for j in range(y):
if any(originalPicture[i, j] == [255, 255, 255]): # 顏色為白色的時(shí)候,占位
distinguishLeaf.append([i, j])
遍歷上述得出的目標(biāo)區(qū)域(已存入數(shù)組中,接下來也就是對數(shù)組進(jìn)行操作)
其中LeafArea是目標(biāo)檢測葉面的面積(多個(gè)像素點(diǎn)的累積值)
greenLeafArea是目標(biāo)葉面中綠色部分的面積(多個(gè)像素點(diǎn)的累積值)
因?yàn)橹白鲞^灰度處理(‘img’圖像),故這里只需查看該像素點(diǎn)值是否為黑(即值是否等于0)
很易得出,非黑色部分為葉片綠色部分,因此一旦確定非黑,像素點(diǎn)個(gè)數(shù) +1
for t in distinguishLeaf:
k, l = t
LeafArea = LeafArea + 1
if img[k, l] != 0:
# print(canny0[k, l])
greenLeafArea += 1
至此,成功了一大半,接下來要做的就是輸出病蟲害葉面占的比重值
scale = 100 - (greenLeafArea/LeafArea)*100
percentage = "病蟲害葉面占比為:" + str(scale) + ' %'
print(percentage)
當(dāng)然,我們可以進(jìn)一步體現(xiàn)一下:若病蟲害葉面遭受病蟲害達(dá)到某一值,及時(shí)提醒農(nóng)名伯伯噴灑農(nóng)藥進(jìn)行防治。
if scale < 95:
easygui.msgbox('警告!葉片遭受病蟲害!請盡早噴灑農(nóng)藥!')
這里再贅述一點(diǎn),就是可以輸出運(yùn)行代碼中每一步的圖像處理結(jié)果,就像這樣
cv2.imwrite("這里是存入本地圖片地址", 這里是要輸出哪一步圖片的代碼名稱)
canny0 = cv2.imread("這里是存入本地圖片地址")
cv2.imshow('這里是圖像標(biāo)題名稱', imutils.resize(canny0))
2.2 總觀代碼
# 導(dǎo)庫
import cv2
import imutils
import easygui
from PIL import Image, ImageDraw, ImageFont
import numpy as np
# foliageNew 作為背景圖,是人為事先在葉子有病蟲害的地方用畫筆涂改為白色的圖片,讀取它
PSpicture = cv2.imread(r"E:foliageNew.png")
# 將圖片 foliageNew 轉(zhuǎn)換為黑白圖像
PSpicture = cv2.cvtColor(PSpicture, cv2.COLOR_BGR2GRAY)
# 對圖片 foliageNew 進(jìn)行高斯處理
PSpictureGS = cv2.GaussianBlur(PSpicture, (21, 21), 0)
# foliageWhite 是葉子目標(biāo)檢測圖,讀取它
originalPicture = cv2.imread(r"E:foliageWhite.png")
# 將圖片 foliageWhite 轉(zhuǎn)換為黑白圖像
originalPicture = cv2.cvtColor(originalPicture, cv2.COLOR_BGR2GRAY)
# 對圖片 foliageWhite 進(jìn)行高斯處理
originalPictureGS = cv2.GaussianBlur(originalPicture, (21, 21), 0)
# 對圖片 foliageNew 和 foliageWhite 做差(對比),返回的結(jié)果代表他們的差異之處
pictureDelta = cv2.absdiff(PSpictureGS, originalPictureGS)
# x, y 是圖片的像素大小
x, y = pictureDelta.shape
# print(x, y)
# pictureDelta 是圖像的區(qū)域,canny 是圖像的輪廓(白色區(qū)域)
img = cv2.GaussianBlur(pictureDelta, (3, 3), 0)
# Canny 邊緣檢測
canny = cv2.Canny(img, 0, 100)
# 定義輪廓(一片葉子)總面積
LeafArea = 0
# 定義綠葉(未被病蟲害葉面)的面積
greenLeafArea = 0
# 定義列表,用來存放要識別的像素點(diǎn)的位置
distinguishLeaf = []
# 畫輪廓,存儲要識別的像素值的位置,記錄在 distinguishLeaf 數(shù)組中
for i in range(x):
for j in range(y):
if any(originalPicture[i, j] == [255, 255, 255]): # 顏色為白色的時(shí)候,占位
distinguishLeaf.append([i, j])
canny0 = cv2.add(originalPictureGS, canny)
# 判斷葉面顏色
for t in distinguishLeaf:
k, l = t
LeafArea = LeafArea + 1
if img[k, l] != 0:
# print(canny0[k, l])
greenLeafArea += 1
# 統(tǒng)計(jì)綠葉占比
scale = 100 - (greenLeafArea/LeafArea)*100
percentage = "病蟲害葉面占比為:" + str(scale) + ' %'
print(percentage)
# cv2.imwrite("這里是存入本地圖片地址", 這里是要輸出哪一步圖片的代碼名稱)
# canny0 = cv2.imread("這里是存入本地圖片地址")
# cv2.imshow('這里是圖像標(biāo)題名稱', imutils.resize(canny0))
if scale < 95:
easygui.msgbox('警告!葉片遭受病蟲害!請盡早噴灑農(nóng)藥!')
# 此行代碼用于避免輸出圖片發(fā)生閃退的現(xiàn)象
key = cv2.waitKey(0)
2.3 項(xiàng)目運(yùn)行結(jié)果
3 總結(jié)展望
從上述運(yùn)行結(jié)果來看,該片葉子已經(jīng)被病蟲害病害了越葉面面積的17%。此值已超過最小病害初定值,故最后彈出窗口顯示“警告!葉片遭受病蟲害!請盡早噴灑農(nóng)藥!”
此項(xiàng)目運(yùn)用簡單實(shí)例,介紹了計(jì)算機(jī)視覺技術(shù)在農(nóng)業(yè)方面的應(yīng)用,在幫助農(nóng)民贈產(chǎn)脫貧方面起到了一定的作用。
這就是“互聯(lián)網(wǎng)+智慧農(nóng)業(yè)”的實(shí)例項(xiàng)目實(shí)現(xiàn)。
版權(quán)聲明:本專欄全部為CSDN博主「IT_change」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議。
轉(zhuǎn)載請附上原文出處鏈接及本聲明。
感謝閱讀 ! 感謝支持 ! 感謝關(guān)注 !
希望本文能對讀者學(xué)習(xí)和理解計(jì)算機(jī)視覺技術(shù)有所幫助,并請讀者批評指正!
2020年5月底于山西大同
END
————————————————
版權(quán)聲明:本文為CSDN博主「榮仔!最靚的仔!」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/IT_charge/article/details/106340456
評論