Python+Yolov5果树上的水果(苹果)检测识别

news2025/1/11 10:18:26

程序示例精选

Python+Yolov5果树上的水果(苹果)检测识别

如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!

前言

这篇博客针对<<Python+Yolov5果树上的水果(苹果)检测识别>>编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

一、所需工具软件

二、使用步骤

        1. 引入库

        2. 代码实现

        3. 运行结果

三、在线协助

一、所需工具软件

1. Python,Pycharm

2. Yolov5

二、使用步骤

1.引入库

import argparse
import time
from pathlib import Path

import cv2
import torch
import torch.backends.cudnn as cudnn
from numpy import random

from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages
from utils.general import check_img_size, check_requirements, check_imshow, non_max_suppression, apply_classifier, \
    scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path
from utils.plots import plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronized

2. 代码实现

代码如下:

def detect(save_img=False):
    source, weights, view_img, save_txt, imgsz = opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
    webcam = source.isnumeric() or source.endswith('.txt') or source.lower().startswith(
        ('rtsp://', 'rtmp://', 'http://'))

    # Directories
    save_dir = Path(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok))  # increment run
    (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir

    # Initialize
    set_logging()
    device = select_device(opt.device)
    half = device.type != 'cpu'  # half precision only supported on CUDA

    # Load model
    model = attempt_load(weights, map_location=device)  # load FP32 model
    stride = int(model.stride.max())  # model stride
    imgsz = check_img_size(imgsz, s=stride)  # check img_size
    if half:
        model.half()  # to FP16

    # Second-stage classifier
    classify = False
    if classify:
        modelc = load_classifier(name='resnet101', n=2)  # initialize
        modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']).to(device).eval()

    # Set Dataloader
    vid_path, vid_writer = None, None
    if webcam:
        view_img = check_imshow()
        cudnn.benchmark = True  # set True to speed up constant image size inference
        dataset = LoadStreams(source, img_size=imgsz, stride=stride)
    else:
        save_img = True
        dataset = LoadImages(source, img_size=imgsz, stride=stride)

    # Get names and colors
    names = model.module.names if hasattr(model, 'module') else model.names
    colors = [[random.randint(0, 255) for _ in range(3)] for _ in names]

    # Run inference
    if device.type != 'cpu':
        model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters())))  # run once
    t0 = time.time()
        # Apply NMS
        pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms)
        t2 = time_synchronized()

        # Apply Classifier
        if classify:
            pred = apply_classifier(pred, modelc, img, im0s)

        # Process detections
        for i, det in enumerate(pred):  # detections per image
            if webcam:  # batch_size >= 1
                p, s, im0, frame = path[i], '%g: ' % i, im0s[i].copy(), dataset.count
            else:
                p, s, im0, frame = path, '', im0s, getattr(dataset, 'frame', 0)

            p = Path(p)  # to Path
            save_path = str(save_dir / p.name)  # img.jpg
            txt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{frame}')  # img.txt
            s += '%gx%g ' % img.shape[2:]  # print string
            gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  # normalization gain whwh
            if len(det):
                # Rescale boxes from img_size to im0 size
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()

                # Print results

                for c in det[:, -1].unique():
                    n = (det[:, -1] == c).sum()  # detections per class
                    s += f"{n} {names[int(c)]}{'s' * (n > 1)}, "  # add to string

  

                # Write results
                for *xyxy, conf, cls in reversed(det):
                    if save_txt:  # Write to file
                        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
                        line = (cls, *xywh, conf) if opt.save_conf else (cls, *xywh)  # label format
                        with open(txt_path + '.txt', 'a') as f:
                            f.write(('%g ' * len(line)).rstrip() % line + '\n')

                    if save_img or view_img:  # Add bbox to image
                        label = f'{names[int(cls)]} {conf:.2f}'
                        plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)

            # Print time (inference + NMS)
            print(f'{s}Done. ({t2 - t1:.3f}s)')

            # Stream results
            if view_img:
                cv2.imshow(str(p), im0)
                cv2.waitKey(1)  # 1 millisecond

            # Save results (image with detections)
            if save_img:
                if dataset.mode == 'image':
                    cv2.imwrite(save_path, im0)
                else:  # 'video'
                    if vid_path != save_path:  # new video
                        vid_path = save_path
                        if isinstance(vid_writer, cv2.VideoWriter):
                            vid_writer.release()  # release previous video writer

                        fourcc = 'mp4v'  # output video codec
                        fps = vid_cap.get(cv2.CAP_PROP_FPS)
                        w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
                        h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
                        vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
                    vid_writer.write(im0)

    if save_txt or save_img:
        s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''
        print(f"Results saved to {save_dir}{s}")

    print(f'Done. ({time.time() - t0:.3f}s)')


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default='yolov5_crack_wall_epoach150_batchsize5.pt', help='model.pt path(s)')
    parser.add_argument('--source', type=str, default='data/images', help='source')  # file/folder, 0 for webcam
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.4, help='object confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    opt = parser.parse_args()
    
    print(opt)
    check_requirements()

    with torch.no_grad():
        if opt.update:  # update all models (to fix SourceChangeWarning)
            for opt.weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
                detect()
                strip_optimizer(opt.weights)
        else:
            detect()

3. 运行结果

 

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作

博主推荐文章:python人脸识别统计人数qt窗体-CSDN博客

博主推荐文章:Python Yolov5火焰烟雾识别源码分享-CSDN博客

                         Python OpenCV识别行人入口进出人数统计_python识别人数-CSDN博客

个人博客主页:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

博主所有文章点这里:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/567520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Data Mongo更新整个对象

第一步&#xff1a;在pom.xml文件中引入下述依赖&#xff0c;当前Spring Boot的版本为 2.7.6&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>…

【产品人卫朋】华为IPD体系:IPD相关术语

目录 术语合集 课程 术语合集 BB&#xff1a;building block&#xff0c;组件 BG&#xff1a;business group&#xff0c;业务群 BLM&#xff1a;business leadership model&#xff0c;业务领先模型 BMT&#xff1a;business management team&#xff0c;业务管理团队 B…

这6个超实用的图片素材网站,高清、免费,赶紧马住

推荐6个超实用的图片素材网站&#xff0c;高清无水印&#xff0c;绝对值得收藏&#xff01; 1、菜鸟图库 https://www.sucai999.com/pic.html#?vNTYxMjky 网站主要是为新手设计师提供免费素材的&#xff0c;素材的质量都很高&#xff0c;类别也很多&#xff0c;像平面、UI、…

Restful接口开发与测试—接口测试

开发完接口&#xff0c;接下来我们需要对我们开发的接口进行测试。接口测试的方法比较多&#xff0c;使用接口工具或者Python来测试都可以&#xff0c;工具方面比如之前我们学习过的Postman或者Jmeter &#xff0c;Python脚本测试可以使用Requests unittest来测试。 测试思路…

数据结构中常见的树

二叉树&#xff1a;每个子节点只有两个节点的树&#xff0c;每个结点至多拥有两棵子树(即二叉树中不存在度大于2的结 点)&#xff0c;并且&#xff0c;二叉树的子树有左右之分&#xff0c;其次序不能任意颠倒 我们一般在解题过程中二叉树有两种主要的形式&#xff1a;满二叉树…

徐延涛:医疗健康企业如何重构客户管理的“营销”与“服务”?

随着人口老龄化和生活健康水平的提升&#xff0c;中国的医疗健康行业市场规模前景向好。《2023易凯资本中国健康产业白皮书》显示&#xff0c;从2022年到2030年的八年里&#xff0c;中国健康产业的整体规模将从10万亿元增长到接近20万亿&#xff0c;年复合增长率将达到9.5%-10%…

TS入门(TS类型有哪些?怎么使用?)

TS简介 TS&#xff08;TypeScript&#xff09;是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;能够为 JavaScript 添加静态类型检查和面向对象编程的特性。TS 可以在编译时进行类型检查&#xff0c;从而提高代码的可读性、可维护性和可靠性&am…

PMP课堂模拟题目及解析(第12期)

111. 客户拒绝了一项交付成果&#xff0c;因为它不符合约定的质量规格&#xff0c;项目团队调查该问题&#xff0c;并确定供应商提供的零件有问题&#xff0c;供应商拒绝纠正这种情况。项目经理应该审查什么&#xff1f; A. 与供应商订立的服务水平协议 B. 采购管理计划和合…

从领英退出中国,解析融云《社交泛娱乐出海作战地图》从0到1出海方法论

近期&#xff0c;“领英职场”宣布将于 2023 年 8 月 9 日起正式停止服务。移步【融云全球互联网通信云】回复“地图”免费领 一时之间&#xff0c;网友纷纷送上祭文。有人觉得猝不及防&#xff0c;但更多人直言并不意外。 领英在中国的折戟终局&#xff0c;似乎从 2021 年改版…

chatgpt赋能python:PythonSave函数:保存和保护你的数据

Python Save函数&#xff1a;保存和保护你的数据 Python Save函数是Python编程中最常用的函数之一。它允许开发者将数据保存到文件或数据库中&#xff0c;在未来的操作中访问和使用。无论你是处理大数据集还是需要保护数据免受未经授权访问&#xff0c;Python Save函数都可以为…

Hegegraph的Gremlin语言(全)

Hegegraph的Gremlin语言&#xff08;全&#xff09; 内容 • 基本概念 • Step讲解 • HugeGraph特有Gremlin语句&#xff08;schema相关&#xff09;基本概念 • Gremlin • 是一门图的查询语言&#xff0c;地位作用与数据库的 SQL相当 • 支持图数据的增、删、改、查 • 图…

鸿蒙Hi3861学习十九-DevEco Device Tool源码获取、编译、下载

一、简介 在上一篇文章中&#xff0c;已经讲述了如何在Windows通过Remote SSH远程连接Linux下的DevEco Device Tool。这篇文章&#xff0c;来说一下关于源码的获取、编译与下载。建议先按照上一篇文章进行环境搭建。 鸿蒙Hi3861学习十八-DevEco Device Tool环境搭建_t_guest的…

运动员最佳配对问题——算法设计与分析(C实现)

目录 一、问题简述 二、分析 三、代码展示 四、结果验证 一、问题简述 问题描述&#xff1a;羽毛球队有男女运动员各n人。给定2个n*n矩阵P和Q。P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞争优势&#xff1b;Q[i][j]是男运动员i和女运动员j配合的女运动员竞…

msvcr110.dll丢失的解决方法,多种方法助你解决msvcr110.dll丢失

当您在尝试打开某个程序或游戏时&#xff0c;可能会看到一个错误消息&#xff0c;提示您的计算机缺少msvcr110.dll文件。这是因为该文件是Microsoft Visual C Redistributable库的一部分&#xff0c;缺少它可能会导致应用程序无法正常运行。在本文中&#xff0c;我们将详细介绍…

【接口测试】JMeter接口关联测试

‍‍1 前言 我们来学习接口管理测试&#xff0c;这就要使用到JMeter提供的JSON提取器和正则表达式提取器了&#xff0c;下面我们来看看是如何使用的吧。 2 JSON提取器 1、添加JSON提取器 在线程组右键 > 添加 > 后置处理器 > JSON提取器 2、JSON提取器参数说明 N…

19-03 基于业务场景的架构技术选型

Java架构师系列导航目录 金融领域的挑战与架构设计 金融领域的方向 借贷保险证券交易 互联网金融 vs 传统金融 满足更广泛群体的金融需求增强金融普惠性提高金融服务效率 互联网金融前景 近十年蓬勃发展&#xff0c;朝阳行业&#xff1a;花呗、借呗、微粒贷、余额宝双刃剑&am…

【案例教程】基于“遥感+”蓝碳储量估算、红树林信息提取实践技术应用与科研论文写作

光谱和图像是人们观察世界的两种方式&#xff0c;高光谱遥感通过“图谱合一”的技术创新将两者结合起来&#xff0c;大大提高了人们对客观世界的认知能力&#xff0c;本来在宽波段遥感中不可探测的物质&#xff0c;在高光谱遥感中能被探测。以高光谱遥感为核心&#xff0c;构建…

动态远程桌面如何用来做爬虫

爬虫需要动态IP主要是为了避免被目标网站封禁或限制访问。如果使用固定IP进行爬取&#xff0c;很容易被目标网站识别出来并封禁&#xff0c;导致无法继续爬取数据。而使用动态IP可以让爬虫在不同的IP地址之间切换&#xff0c;降低被封禁的风险。此外&#xff0c;动态IP还可以帮…

Ebay、亚马逊高低单价产品如何打造?自养号测评策略解析

很多卖家都认为低单价产品太卷了&#xff0c;于是选择了进入了高单价细分类目&#xff0c;一进入&#xff0c;发现广告竞价高到自己无法接受&#xff0c;转化还特别差&#xff0c;然后一直在挣扎中。眼下整个跨境市场&#xff0c;无论是高单价产品&#xff0c;还是低单价产品&a…

redis-server源码

1 redis主流程 redis启动流程: 1 加载配置&#xff1b;2 初始化redis master、slave以及sentinel的sri&#xff1b;3 注册事件事件serverCron。 <span style"background-color:#f5f2f0"><span style"color:black"><span style"color:…