互联网+智慧农业:计算机视觉技术在农作物病虫害检测方面的应用

2021-02-02 17:45:48 浏览数 (1)

农作物病虫害是我国的主要农业灾害之一,它具有种类多、影响大、并时常暴发成灾的特点,其发生范围和严重程度对我国国民经济、特别是农业生产常造成重大损失。 随着计算机科学技术的飞速发展,现已有非常多的 AI 方法手段应用于病虫害目标检测、防治,进而运用现代技术助力赠产脱贫! 本文将从计算机视觉技术出发,运用Python语言简要分析目标检测在农作物病虫害方面的研究与应用。

目录

1 项目简介

1.1 项目概述

1.2 前期准备

2 项目分析

2.1 代码详解

2.2 总观代码

2.3 项目运行结果

3 总结展望


1 项目简介

1.1 项目概述

本项目旨在运用Python语言分析和阐述计算机视觉技术中的目标检测在农作物病虫害方面的应用。具体而言,我们将运用Python语言运行并得出目标叶面中已遭受病虫害的面积,然后分析是否需要进行农药喷洒等防治病虫害的进一步肆虐,进而帮助农名伯伯更好地管理农作物,减少损失、增加产量……

1.2 前期准备

首先,寻找检测目标:这里我们针对一片部分遭受病虫害的叶片进行检测处理

对叶片分析处理用到python语言及部分第三方库

在这里: Python环境:3.8.2

python编译器:JetBrains PyCharm 2018.1.2 x64

第三方库:OpenCV、ilmutils、easygui、numpy、PIL

2 项目分析

2.1 代码详解

导入用到的所有库

代码语言:javascript复制
import cv2
import imutils
import easygui
from PIL import Image, ImageDraw, ImageFont
import numpy as np

事先将有病虫害的叶片部分做画图处理(涂成白色) 背景图

导入图片并做黑白处理

代码语言:javascript复制
# foliageNew 作为背景图,是人为事先在叶子有病虫害的地方用画笔涂改为白色的图片,读取它
PSpicture = cv2.imread(r"E:foliageNew.png")
# 将图片 foliageNew 转换为黑白图像
PSpicture = cv2.cvtColor(PSpicture, cv2.COLOR_BGR2GRAY)

对背景图再做高斯处理

代码语言:javascript复制
# 对图片 foliageNew 进行高斯处理
PSpictureGS = cv2.GaussianBlur(PSpicture, (21, 21), 0)

同时事先将目标检测叶片同样做画图处理(涂成白色)

对其做相同处理

代码语言:javascript复制
# foliageWhite 是叶子目标检测图,读取它
originalPicture = cv2.imread(r"E:foliageWhite.png")
# 将图片 foliageWhite 转换为黑白图像
originalPicture = cv2.cvtColor(originalPicture, cv2.COLOR_BGR2GRAY)
# 对图片 foliageWhite 进行高斯处理
originalPictureGS = cv2.GaussianBlur(originalPicture, (21, 21), 0)

对两张处理后的图片做差,返回的值代表其差异之处

代码语言:javascript复制
# 对图片 foliageNew 和 foliageWhite 做差(对比),返回的结果代表他们的差异之处
pictureDelta = cv2.absdiff(PSpictureGS, originalPictureGS)

因为之后要用到相关数据,所以事先查看图片像素大小

代码语言:javascript复制
# x, y 是图片的像素大小
x, y = pictureDelta.shape
print(x, y)

此值与图片属性中所示的值相同,这也正是我们期望的结果

当然,这里我们可以做一下边缘检测进一步确认我们想要的检测目标区域

代码语言:javascript复制
# pictureDelta 是图像的区域,canny 是图像的轮廓(白色区域)
img = cv2.GaussianBlur(pictureDelta, (3, 3), 0)
# Canny 边缘检测
canny = cv2.Canny(img, 0, 100)

确定目标检测区域(这里是轮廓区域,不是整个图像区域) 即在第二次做高斯处理的那个图像上确定检测区域(像素值为白的区域就是我们想要的目标区域)

代码语言:javascript复制
# 画轮廓,存储要识别的像素值的位置,记录在 distinguishLeaf 数组中
for i in range(x):
    for j in range(y):
        if any(originalPicture[i, j] == [255, 255, 255]):  # 颜色为白色的时候,占位
            distinguishLeaf.append([i, j])

遍历上述得出的目标区域(已存入数组中,接下来也就是对数组进行操作) 其中LeafArea是目标检测叶面的面积(多个像素点的累积值) greenLeafArea是目标叶面中绿色部分的面积(多个像素点的累积值) 因为之前做过灰度处理(‘img’图像),故这里只需查看该像素点值是否为黑(即值是否等于0)

很易得出,非黑色部分为叶片绿色部分,因此一旦确定非黑,像素点个数 1

代码语言:javascript复制
for t in distinguishLeaf:
    k, l = t
    LeafArea = LeafArea   1
    if img[k, l] != 0:
        # print(canny0[k, l])
        greenLeafArea  = 1

至此,成功了一大半,接下来要做的就是输出病虫害叶面占的比重值

代码语言:javascript复制
scale = 100 - (greenLeafArea/LeafArea)*100
percentage = "病虫害叶面占比为:"   str(scale)   ' %'
print(percentage)

当然,我们可以进一步体现一下:若病虫害叶面遭受病虫害达到某一值,及时提醒农名伯伯喷洒农药进行防治。

代码语言:javascript复制
if scale < 95:
    easygui.msgbox('警告!叶片遭受病虫害!请尽早喷洒农药!')

这里再赘述一点,就是可以输出运行代码中每一步的图像处理结果,就像这样

代码语言:javascript复制
cv2.imwrite("这里是存入本地图片地址", 这里是要输出哪一步图片的代码名称)
canny0 = cv2.imread("这里是存入本地图片地址")
cv2.imshow('这里是图像标题名称', imutils.resize(canny0))

2.2 总观代码

代码语言:javascript复制
# 导库
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 转换为黑白图像
PSpicture = cv2.cvtColor(PSpicture, cv2.COLOR_BGR2GRAY)
# 对图片 foliageNew 进行高斯处理
PSpictureGS = cv2.GaussianBlur(PSpicture, (21, 21), 0)
# foliageWhite 是叶子目标检测图,读取它
originalPicture = cv2.imread(r"E:foliageWhite.png")
# 将图片 foliageWhite 转换为黑白图像
originalPicture = cv2.cvtColor(originalPicture, cv2.COLOR_BGR2GRAY)
# 对图片 foliageWhite 进行高斯处理
originalPictureGS = cv2.GaussianBlur(originalPicture, (21, 21), 0)
# 对图片 foliageNew 和 foliageWhite 做差(对比),返回的结果代表他们的差异之处
pictureDelta = cv2.absdiff(PSpictureGS, originalPictureGS)
# x, y 是图片的像素大小
x, y = pictureDelta.shape
# print(x, y)

# pictureDelta 是图像的区域,canny 是图像的轮廓(白色区域)
img = cv2.GaussianBlur(pictureDelta, (3, 3), 0)
# Canny 边缘检测
canny = cv2.Canny(img, 0, 100)

# 定义轮廓(一片叶子)总面积
LeafArea = 0
# 定义绿叶(未被病虫害叶面)的面积
greenLeafArea = 0
# 定义列表,用来存放要识别的像素点的位置
distinguishLeaf = []

# 画轮廓,存储要识别的像素值的位置,记录在 distinguishLeaf 数组中
for i in range(x):
    for j in range(y):
        if any(originalPicture[i, j] == [255, 255, 255]):  # 颜色为白色的时候,占位
            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

# 统计绿叶占比
scale = 100 - (greenLeafArea/LeafArea)*100
percentage = "病虫害叶面占比为:"   str(scale)   ' %'
print(percentage)

# cv2.imwrite("这里是存入本地图片地址", 这里是要输出哪一步图片的代码名称)
# canny0 = cv2.imread("这里是存入本地图片地址")
# cv2.imshow('这里是图像标题名称', imutils.resize(canny0))

if scale < 95:
    easygui.msgbox('警告!叶片遭受病虫害!请尽早喷洒农药!')

# 此行代码用于避免输出图片发生闪退的现象
key = cv2.waitKey(0)

2.3 项目运行结果

3 总结展望

从上述运行结果来看,该片叶子已经被病虫害病害了越叶面面积的17%。此值已超过最小病害初定值,故最后弹出窗口显示“警告!叶片遭受病虫害!请尽早喷洒农药!”

此项目运用简单实例,介绍了计算机视觉技术在农业方面的应用,在帮助农民赠产脱贫方面起到了一定的作用。

这就是“互联网 智慧农业”的实例项目实现。


版权声明:本专栏全部为CSDN博主「IT_change」的原创文章,遵循 CC 4.0 BY-SA 版权协议。 转载请附上原文出处链接及本声明。

感谢阅读 ! 感谢支持 ! 感谢关注 !

希望本文能对读者学习和理解计算机视觉技术有所帮助,并请读者批评指正!

2020年5月底于山西大同

END

0 人点赞