计算机毕业设计 机器视觉害虫种类及数量检测系统(源码+论文)

本文主要是介绍计算机毕业设计 机器视觉害虫种类及数量检测系统(源码+论文),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 0 项目说明
  • 1 研究目的
  • 2 研究内容及结论
  • 3 文件介绍
  • 4 论文目录
  • 5 项目源码


0 项目说明

基于机器视觉的害虫种类及数量检测

提示:适合用于课程设计或毕业设计,工作量达标,源码开放

项目分享:

https://gitee.com/asoonis/feed-neo


1 研究目的

研究的目的在于建立一套远程病虫害自动识别系统,有助于缓解农业植保人员和病虫害鉴定专家的人力资源紧张,有助于病虫害知识有限的农业人员进行及时的病虫害检测,并且,通过害虫种类数目的监测和信息收集,定期对昆虫数据进行整理和分析,建立病虫害爆发的规律模型,进而预测判断病虫害爆发的时间,及时通知农业植物保护人员和农户进行合理地科学地预防。提高农作物产量和质量。

2 研究内容及结论

(1) 设计实现了一套可适用于野外的害虫捕获和图像采集装置。该装置放置在农业种植区域,24 小时进行害虫的诱杀和图像采集,同时,装置可以通过无线网络将害虫图像上传至农业监控中心虫类鉴别服务器,并进行害虫种类的识别,进行产区内害虫种类数目的信息收集。

(2) 开发了一套基于机器视觉的昆虫计数工作方法。开发了一套的适用于苍蝇粘板等包含多数昆虫设备的图像的基于机器视觉的昆虫计数工作方法。该方法首先对包含多数昆虫的图片进行二值化预处理,然后进行轮廓的查找,并进行轮廓的计数,得到的数目反映了图片中的昆虫数目的数量级。该方法适用于苍蝇粘板图像等包含多数昆虫虫体的图像上。

(3) 开发了一套基于机器视觉的昆虫识别工作方法和流程。该方法在参考已有研究成果的基础山,选取了昆虫形态特征中的昆虫矩形度、昆虫延长度、昆虫圆形度、昆虫球状性、昆虫叶状性等 5 个特征,进行昆虫图像的特征提取。之后,采用逻辑斯蒂回归模型、线性 SVM 模型和 K 邻近分类器分别进行训练,并测试比较训练结果,以进行分类器算法的筛选。该方法适用于本套图像采集装置。

(4) 设计了一套远程害虫自动识别系统。结合上述三个功能,该系统可以实现:在图像采集节点进行害虫捕获和昆虫图像采集,在虫类鉴别服务器进行昆虫图像的识别和分类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 文件介绍

用户界面
MainWindow.ui———————–PyQtDesigner设计的主界面文件
MainWindow.py———————-PyUIC转换而成的主界面程序

运行逻辑
VideoMainWindow.py————–PyQt结合OpenCV实现在界面中显示视频画面
PreProcess.py————————-对源数据样本进行预处理

特征提取
P_circle.py——————————似圆度
P_extend.py—————————-延长度
P_leaf.py——————————–叶状性
P_rect.py——————————–矩形度
P_spherical.py————————球形度
GetFeatures.py———————–提取特征的模块
GetFiveFeatures.py—————–五个特征提取的测试代码
FeatureExtract.py——————-提取样本库特征保存到CSV文件

机器学习模块
LinearSVM.py————————-线性SVM分类器的训练和模型保存
LinearRegression.py—————逻辑回归分类器的训练和模型保存
KneiborsClassfier.py—————KNN分类器的训练和模型保存
Predict.py——————————加载预训练模型,对特征进行预测
Thresholding.py—————————大津法程序实现和OpenCV大津法函数的效果对比
Count.py————————————-实现加载图片,二值化(大津法),查找轮廓进行计数的效果
GetChineseName.py——————–分类中英文转换

4 论文目录

摘 要 
ABSTRACT 
目 录 
第 1 章 绪论 
1.1 课题研究的背景和意义
1.2 国内外研究现状 
1.2.1 国内研究现状 
1.2.2 国外研究现状 
1.3 研究的内容和目的
1.3.1 研究内容 
1.3.2 研究目的 
1.4 章节安排 
第 2 章 系统总体设计 
2.1 系统设计目标 
2.2 系统总体架构 
2.3 图像采集节点 
2.3.1 装置总体设计 
2.3.2 运行流程 
2.4 虫类鉴别服务器和虫类信息数据库设计
2.4.1 服务器设计 
2.4.2 服务器虫类分类器实现 
2.4.3 PC 上的昆虫分类识别软件 
第 3 章 昆虫图像预处理与计数研究
3.1 昆虫图像的采集 
3.2 昆虫图像的预处理 
III3.2.1 图像的灰度化,高斯滤波和尺度变换
3.2.2 二值化 
3.2.3 大津法 OTSU 在昆虫图像二值化上的应用 
3.3 昆虫图像的计数
3.3.1 检测轮廓 
3.3.2 昆虫计数 
第 4 章 昆虫图像特征提取与识别研究 
4.1 特征的选取 
4.2 特征描述以及提取方式
4.3 分类器的选择和训练
4.4 机器学习结果分析 
4.4.1 性能评价指标 
4.4.2 三种分类器的性能比较 
第 5 章 总结与展望 
5.1 总结 
5.1.1 完成的工作
5.1.2 创新点和不足之处 
5.2 展望 
致谢

5 项目源码

# coding=utf-8
# 先读图,然后二值化,
# 延长度import cv2
import math
import numpy as np
from matplotlib import pyplot as plt#  此处读入图片,作为接口
origin = cv2.imread('dataset/fly6.jpg')
grayimage = cv2.imread('dataset/fly6.jpg', 0)#  高斯滤波
blur = cv2.GaussianBlur(grayimage, (5, 5), 0)#  二值化:用大津法,此处选项若是THRESH_BINARY_INV,则同意选用白色背景的图片样本
ret, otsu = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 找轮廓
contours = cv2.findContours(otsu, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 轮廓集数目largest_area = 0
largest_contour_index = 0
num = len(contours[1])
for i in range(num):area = cv2.contourArea(contours[1][i], False)if area > largest_area:largest_area = arealargest_contour_index = imaxContour = contours[1][largest_contour_index]
# 画轮廓
cv2.drawContours(origin, maxContour, -1, (0, 0, 255), 2)
print "最大面积" + str(largest_area)# 质心计算
M = cv2.moments(maxContour)
Centroid_x = int(M['m10'] / M['m00'])
Centroid_y = int(M['m01'] / M['m00'])
print "质心" + str(Centroid_x) + " " + str(Centroid_y)
cv2.circle(origin, (Centroid_x, Centroid_y), 8, (255, 255, 255), -1)# 获取长轴
Major_Axis_Length = 0
Major_Axis_Angle = 0
Major_Axis_End_x = 0
Major_Axis_End_y = 0
Major_Axis_Begin_x = 0
Major_Axis_Begin_y = 0# 此处需要注意质心是否在轮廓内
# 找长轴
for angle in range(180):theta = angle * 3.14 / 180.0lengthBackward = 0lengthForward = 0point_End_x = Centroid_xpoint_End_y = Centroid_ypoint_Begin_x = Centroid_xpoint_Begin_y = Centroid_y# 步进越小准确率越高,设置成1可以先找到准确的直线角度,再根据角度和质心得到的直线计算出正确的长轴和轮廓交点while cv2.pointPolygonTest(maxContour, (point_End_x, point_End_y), False) > 0:lengthForward = lengthForward + 0.1point_End_x = int(round(point_End_x + lengthForward * math.cos(theta)))point_End_y = int(round(point_End_y + lengthForward * math.sin(theta)))while cv2.pointPolygonTest(maxContour, (point_Begin_x, point_Begin_y), False) > 0:lengthBackward = lengthBackward + 0.1point_Begin_x = int(round(point_Begin_x - lengthBackward * math.cos(theta)))point_Begin_y = int(round(point_Begin_y - lengthBackward * math.sin(theta)))if lengthForward + lengthBackward >= Major_Axis_Length:Major_Axis_Length = lengthForward + lengthBackwardMajor_Axis_Angle = angleMajor_Axis_End_x = point_End_xMajor_Axis_End_y = point_End_yMajor_Axis_Begin_x = point_Begin_xMajor_Axis_Begin_y = point_Begin_y# 计算实际长轴长度
Real_Major_Axis_Length = math.sqrt(math.pow((Major_Axis_End_x - Major_Axis_Begin_x), 2) + math.pow((Major_Axis_End_y - Major_Axis_Begin_y), 2))Real_Major_Axis_Length = round(Real_Major_Axis_Length, 1)
print "长轴长度 = " + str(Real_Major_Axis_Length)
print "长轴角度 = " + str(Major_Axis_Angle)
# print "起点 = " + "x: " + str(Major_Axis_Begin_x) + "  y: " + str(Major_Axis_Begin_y)
# print "起点 = " + "x: " + str(Major_Axis_End_x) + "  y: " + str(Major_Axis_End_y)# 画长轴
cv2.line(origin, (Major_Axis_Begin_x, Major_Axis_Begin_y), (Major_Axis_End_x, Major_Axis_End_y), (255, 0, 0), 2)# 找短轴
# 1. 先得到长轴直线的表达式y=k*x+b,用来计算点到直线距离和判断点在直线上方还是下方
Major_Axis_k = math.tan(Major_Axis_Angle * 3.14 / 180.0)
Major_Axis_b = Centroid_y - Major_Axis_k * Centroid_x# 2. 点(x0,y0)到直线(Ax+By+C=0)的距离为d =abs (A*x0+B*y0+C)/sqrt(A^2+B^2)
Minor_Axis_A = Major_Axis_k
Minor_Axis_B = -1
Minor_Axis_C = Major_Axis_b# 3. 遍历轮廓上的点
Minor_Axis_Under_length = 0
Minor_Axis_Above_length = 0
Minor_Axis_Under_End_x = 0
Minor_Axis_Under_End_y = 0
Minor_Axis_Above_End_x = 0
Minor_Axis_Above_End_y = 0# 轮廓点集
ContourItems = maxContour.shape[0]
for item in range(ContourItems):point_x = maxContour[item][0][0]point_y = maxContour[item][0][1]# 判断点在直线哪一侧# 上侧if point_y > int(Major_Axis_k * point_x + Major_Axis_b):# 点到直线距离dis = abs((Minor_Axis_A * point_x + Minor_Axis_B * point_y + Minor_Axis_C) / math.sqrt(Minor_Axis_A * Minor_Axis_A + Minor_Axis_B * Minor_Axis_B))if dis >= Minor_Axis_Above_length:Minor_Axis_Above_length = disMinor_Axis_Above_End_x = point_xMinor_Axis_Above_End_y = point_y# 下侧elif point_y < int(Major_Axis_k * point_x + Major_Axis_b):# 点到直线距离dis = abs((Minor_Axis_A * point_x + Minor_Axis_B * point_y + Minor_Axis_C) / math.sqrt(Minor_Axis_A * Minor_Axis_A + Minor_Axis_B * Minor_Axis_B))if dis >= Minor_Axis_Under_length:Minor_Axis_Under_length = disMinor_Axis_Under_End_x = point_xMinor_Axis_Under_End_y = point_y# 第三种可能就是轮廓与直线的交点# # 标记两个点,可以忽略
cv2.circle(origin, (Minor_Axis_Above_End_x, Minor_Axis_Above_End_y), 4, (255, 255, 255), -1)
cv2.circle(origin, (Minor_Axis_Under_End_x, Minor_Axis_Under_End_y), 4, (255, 255, 255), -1)
# 画出两点直线
cv2.line(origin, (Minor_Axis_Under_End_x, Minor_Axis_Under_End_y), (Minor_Axis_Above_End_x, Minor_Axis_Above_End_y),(0, 255, 255), 3)# 计算实际短轴长度
Real_Minor_Axis_Length = math.sqrt(math.pow((Minor_Axis_Above_End_x - Minor_Axis_Under_End_x), 2) + math.pow((Minor_Axis_Above_End_y - Minor_Axis_Under_End_y), 2))Real_Minor_Axis_Length = round(Real_Minor_Axis_Length, 1)
print "短轴长度 = " + str(Real_Minor_Axis_Length)P_extend = Real_Minor_Axis_Length * 1.0 / Real_Major_Axis_Length
P_extend = round(P_extend, 3)print "延长度 = " + str(P_extend)
# 画出与长轴距离最远的两点的辅助线,使用时可以不用,画图用作论文使用
# 画出长轴右方
line_above_k = math.tan((Major_Axis_Angle - 90) * 3.14 / 180.0)
line_above_b = Minor_Axis_Above_End_y - line_above_k * Minor_Axis_Above_End_x
Minor_Axis_Above_Begin_x = int((line_above_b - Major_Axis_b) / (Major_Axis_k - line_above_k))
Minor_Axis_Above_Begin_y = int(line_above_k * Minor_Axis_Above_Begin_x + line_above_b)
cv2.line(origin, (Minor_Axis_Above_Begin_x, Minor_Axis_Above_Begin_y), (Minor_Axis_Above_End_x, Minor_Axis_Above_End_y),(255, 0, 255), 3)line_under_k = math.tan((Major_Axis_Angle - 90) * 3.14 / 180.0)
line_under_b = Minor_Axis_Under_End_y - line_under_k * Minor_Axis_Under_End_x
Minor_Axis_Under_Begin_x = int((line_under_b - Major_Axis_b) / (Major_Axis_k - line_under_k))
Minor_Axis_Under_Begin_y = int(line_under_k * Minor_Axis_Under_Begin_x + line_under_b)
cv2.line(origin, (Minor_Axis_Under_Begin_x, Minor_Axis_Under_Begin_y), (Minor_Axis_Under_End_x, Minor_Axis_Under_End_y),(255, 255, 0), 3)cv2.putText(origin, 'Major_Axis : ' + str(Real_Major_Axis_Length), (280, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 155), 2, cv2.LINE_AA)
cv2.putText(origin, 'Minor_Axis : ' + str(Real_Minor_Axis_Length), (280, 85), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 155), 2, cv2.LINE_AA)
cv2.putText(origin, 'P_Rect: ' + str(P_extend), (280, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 155), 2, cv2.LINE_AA)# 显示
cv2.namedWindow('Butterfly', cv2.WINDOW_AUTOSIZE)
cv2.imshow('Butterfly', origin)
cv2.imwrite('picture/p-extend.png',origin)k = cv2.waitKey(0)# 'ESC'
if k == 27:cv2.destroyAllWindows()

项目分享:

https://gitee.com/asoonis/feed-neo

这篇关于计算机毕业设计 机器视觉害虫种类及数量检测系统(源码+论文)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/yunhai66/article/details/129693637
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/316499

相关文章

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想