news 2026/6/24 0:20:41

毕业设计 基于深度学习的水果识别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
毕业设计 基于深度学习的水果识别

文章目录

  • 1 前言
  • 2 开发简介
  • 3 识别原理
    • 3.1 传统图像识别原理
    • 3.2 深度学习水果识别
  • 4 数据集
  • 5 部分关键代码
    • 5.1 处理训练集的数据结构
    • 5.2 模型网络结构
    • 5.3 训练模型
  • 6 识别效果

1 前言

🔥这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。并且很难找到完整的毕设参考学习资料。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目提供大家参考学习,今天要分享的是

🧿选题指导, 项目分享:见文末

2 开发简介

深度学习作为机器学习领域内新兴并且蓬勃发展的一门学科, 它不仅改变着传统的机器学习方法, 也影响着我们对人类感知的理解, 已经在图像识别和语音识别等领域取得广泛的应用。 因此, 本文在深入研究深度学习理论的基础上, 将深度学习应用到水果图像识别中, 以此来提高了水果图像的识别性能。

3 识别原理

3.1 传统图像识别原理

传统的水果图像识别系统的一般过程如下图所示,主要工作集中在图像预处理和特征提取阶段。

在大多数的识别任务中, 实验所用图像往往是在严格限定的环境中采集的, 消除了外界环境对图像的影响。 但是实际环境中图像易受到光照变化、 水果反光、 遮挡等因素的影响, 这在不同程度上影响着水果图像的识别准确率。

在传统的水果图像识别系统中, 通常是对水果的纹理、 颜色、 形状等特征进行提取和识别。

3.2 深度学习水果识别

CNN 是一种专门为识别二维特征而设计的多层神经网络, 它的结构如下图所示,这种结构对平移、 缩放、 旋转等变形具有高度的不变性。

学长本次采用的 CNN 架构如图:

4 数据集

  • 数据库分为训练集(train)和测试集(test)两部分

  • 训练集包含四类apple,orange,banana,mixed(多种水果混合)四类237张图片;测试集包含每类图片各两张。图片集如下图所示。

  • 图片类别可由图片名称中提取。

训练集图片预览

测试集预览

数据集目录结构

5 部分关键代码

5.1 处理训练集的数据结构

importosimportpandasaspd train_dir='./Training/'test_dir='./Test/'fruits=[]fruits_image=[]foriinos.listdir(train_dir):forimage_filenameinos.listdir(train_dir+i):fruits.append(i)# name of the fruitfruits_image.append(i+'/'+image_filename)train_fruits=pd.DataFrame(fruits,columns=["Fruits"])train_fruits["Fruits Image"]=fruits_imageprint(train_fruits)

5.2 模型网络结构

importmatplotlib.pyplotaspltimportseabornassnsfromkeras.preprocessing.imageimportImageDataGenerator,img_to_array,load_imgfromglobimportglobfromkeras.modelsimportSequentialfromkeras.layersimportConv2D,MaxPooling2D,Activation,Dropout,Flatten,Dense img=load_img(train_dir+"Cantaloupe 1/r_234_100.jpg")plt.imshow(img)plt.axis("off")plt.show()array_image=img_to_array(img)# shape (100,100)print("Image Shape --> ",array_image.shape)# 131个类目fruitCountUnique=glob(train_dir+'/*')numberOfClass=len(fruitCountUnique)print("How many different fruits are there --> ",numberOfClass)# 构建模型model=Sequential()model.add(Conv2D(32,(3,3),input_shape=array_image.shape))model.add(Activation("relu"))model.add(MaxPooling2D())model.add(Conv2D(32,(3,3)))model.add(Activation("relu"))model.add(MaxPooling2D())model.add(Conv2D(64,(3,3)))model.add(Activation("relu"))model.add(MaxPooling2D())model.add(Flatten())model.add(Dense(1024))model.add(Activation("relu"))model.add(Dropout(0.5))# 区分131类model.add(Dense(numberOfClass))# outputmodel.add(Activation("softmax"))model.compile(loss="categorical_crossentropy",optimizer="rmsprop",metrics=["accuracy"])print("Target Size --> ",array_image.shape[:2])

5.3 训练模型

train_datagen=ImageDataGenerator(rescale=1./255,shear_range=0.3,horizontal_flip=True,zoom_range=0.3)test_datagen=ImageDataGenerator(rescale=1./255)epochs=100batch_size=32train_generator=train_datagen.flow_from_directory(train_dir,target_size=array_image.shape[:2],batch_size=batch_size,color_mode="rgb",class_mode="categorical")test_generator=test_datagen.flow_from_directory(test_dir,target_size=array_image.shape[:2],batch_size=batch_size,color_mode="rgb",class_mode="categorical")fordata_batch,labels_batchintrain_generator:print("data_batch shape --> ",data_batch.shape)print("labels_batch shape --> ",labels_batch.shape)breakhist=model.fit_generator(generator=train_generator,steps_per_epoch=1600//batch_size,epochs=epochs,validation_data=test_generator,validation_steps=800//batch_size)#保存模型 model_fruits.h5model.save('model_fruits.h5')

顺便输出训练曲线

#展示损失模型结果plt.figure()plt.plot(hist.history["loss"],label="Train Loss",color="black")plt.plot(hist.history["val_loss"],label="Validation Loss",color="darkred",linestyle="dashed",markeredgecolor="purple",markeredgewidth=2)plt.title("Model Loss",color="darkred",size=13)plt.legend()plt.show()#展示精确模型结果plt.figure()plt.plot(hist.history["accuracy"],label="Train Accuracy",color="black")plt.plot(hist.history["val_accuracy"],label="Validation Accuracy",color="darkred",linestyle="dashed",markeredgecolor="purple",markeredgewidth=2)plt.title("Model Accuracy",color="darkred",size=13)plt.legend()plt.show()

6 识别效果

fromtensorflow.keras.modelsimportload_modelimportosimportpandasaspdfromkeras.preprocessing.imageimportImageDataGenerator,img_to_array,load_imgimportcv2,matplotlib.pyplotasplt,numpyasnpfromkeras.preprocessingimportimage train_datagen=ImageDataGenerator(rescale=1./255,shear_range=0.3,horizontal_flip=True,zoom_range=0.3)model=load_model('model_fruits.h5')batch_size=32img=load_img("./Test/Apricot/3_100.jpg",target_size=(100,100))plt.imshow(img)plt.show()array_image=img_to_array(img)array_image=array_image*1./255x=np.expand_dims(array_image,axis=0)images=np.vstack([x])classes=model.predict_classes(images,batch_size=10)print(classes)train_dir='./Training/'train_generator=train_datagen.flow_from_directory(train_dir,target_size=array_image.shape[:2],batch_size=batch_size,color_mode="rgb",class_mode="categorical”)print(train_generator.class_indices)

fig=plt.figure(figsize=(16,16))axes=[]files=[]predictions=[]true_labels=[]rows=5cols=2# 随机选择几个图片defgetRandomImage(path,img_width,img_height):"""function loads a random image from a random folder in our test path"""folders=list(filter(lambdax:os.path.isdir(os.path.join(path,x)),os.listdir(path)))random_directory=np.random.randint(0,len(folders))path_class=folders[random_directory]file_path=os.path.join(path,path_class)file_names=[fforfinos.listdir(file_path)ifos.path.isfile(os.path.join(file_path,f))]random_file_index=np.random.randint(0,len(file_names))image_name=file_names[random_file_index]final_path=os.path.join(file_path,image_name)returnimage.load_img(final_path,target_size=(img_width,img_height)),final_path,path_classdefdraw_test(name,pred,im,true_label):BLACK=[0,0,0]expanded_image=cv2.copyMakeBorder(im,160,0,0,300,cv2.BORDER_CONSTANT,value=BLACK)cv2.putText(expanded_image,"predicted: "+pred,(20,60),cv2.FONT_HERSHEY_SIMPLEX,0.85,(255,0,0),2)cv2.putText(expanded_image,"true: "+true_label,(20,120),cv2.FONT_HERSHEY_SIMPLEX,0.85,(0,255,0),2)returnexpanded_image IMG_ROWS,IMG_COLS=100,100# predicting imagesforiinrange(0,10):path="./Test"img,final_path,true_label=getRandomImage(path,IMG_ROWS,IMG_COLS)files.append(final_path)true_labels.append(true_label)x=image.img_to_array(img)x=x*1./255x=np.expand_dims(x,axis=0)images=np.vstack([x])classes=model.predict_classes(images,batch_size=10)predictions.append(classes)class_labels=train_generator.class_indices class_labels={v:kfork,vinclass_labels.items()}class_list=list(class_labels.values())foriinrange(0,len(files)):image=cv2.imread(files[i])image=draw_test("Prediction",class_labels[predictions[i][0]],image,true_labels[i])axes.append(fig.add_subplot(rows,cols,i+1))plt.imshow(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))plt.grid(False)plt.axis('off')plt.show()

🧿 项目分享:大家可自取用于参考学习,获取方式见文末!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 13:03:14

毕业设计 深度学习yolov11痤疮检测医疗辅助系统(源码+论文)

文章目录0 前言1 项目运行效果2 课题背景2.1、痤疮的医学背景与社会影响2.2、传统痤疮诊断方法的技术局限2.2.1 视觉评估法2.2.2 摄影记录法2.2.3 皮肤镜检测2.3、计算机视觉在皮肤病诊断中的发展3.1 早期图像处理方法(2000-2010)2.3.2 机器学习时代(2011-2015)2.4、深度学习带…

作者头像 李华
网站建设 2026/6/23 15:49:44

AppSync Unified:iOS设备应用签名验证的终极解决方案

AppSync Unified:iOS设备应用签名验证的终极解决方案 【免费下载链接】AppSync Unified AppSync dynamic library for iOS 5 and above. 项目地址: https://gitcode.com/gh_mirrors/ap/AppSync 想要在越狱的iOS设备上自由安装任意IPA应用包吗?App…

作者头像 李华
网站建设 2026/6/23 15:21:52

大麦APP抢票技术分享

大麦APP抢票技术探讨重要提醒:本文仅供学习交流,请勿用于任何非法目的,严禁商业化利用或参与黄牛活动!一、背景与动机 每逢热门演唱会或大型体育赛事开售,大麦APP上的门票几乎"秒空"。普通用户眼睁睁看着刷新…

作者头像 李华
网站建设 2026/6/23 20:23:52

C语言编程练习(二)

常见的C语言编程练习类型包括基础语法应用、数组操作、循环控制和算法实现。1、输入一个年份,判断该年是否为闰年,若为闰年则输出“yes”,否则输出“no”。2、从键盘输入3个数,将其从小到大排序后输出

作者头像 李华
网站建设 2026/6/23 20:23:49

GQRX:开启无线电探索之旅的强大开源工具

GQRX:开启无线电探索之旅的强大开源工具 【免费下载链接】gqrx 项目地址: https://gitcode.com/gh_mirrors/gqr/gqrx 想要探索看不见的无线电波世界吗?GQRX就是你的理想入门工具!这款基于Qt和GNU Radio的开源软件定义无线电(SDR)接收…

作者头像 李华
网站建设 2026/6/23 10:20:37

常见进制介绍以及之间的转换(二)

常见进制介绍以及之间的转换1.表示一般情况下,在数字后面用特点的字母(下标)表示该数的进制 二进制;B 十进制:D(可以省略O) 八进制:O 十六进制:H 同时也可以用数字后面加…

作者头像 李华