基于深度学习YOLOv10的皮肤病识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍

项目背景

皮肤病是全球范围内常见的健康问题,早期诊断和治疗对患者的康复至关重要。然而,皮肤病的种类繁多,临床表现复杂,传统的诊断方式主要依赖医生的经验和肉眼观察,存在以下问题:

  1. 诊断效率低:医生需要花费大量时间分析病变区域。

  2. 误诊率高:不同皮肤病的外观可能相似,容易导致误诊。

  3. 资源分布不均:优质医疗资源集中在大城市,偏远地区患者难以获得及时诊断。

近年来,基于深度学习的目标检测技术(如YOLO系列)在医学图像分析领域取得了显著进展。YOLOv10作为YOLO系列的最新版本,具有更高的检测速度和精度,非常适合应用于皮肤病检测场景。本项目旨在利用YOLOv10算法,结合皮肤病图像数据,开发一套高效、准确的皮肤病检测系统,为皮肤病诊断提供智能化支持。


项目意义

  1. 提升诊断效率:通过自动化检测,减少医生的工作负担,提高诊断速度。

  2. 提高诊断准确性:利用深度学习算法,降低误诊率,提升诊断的可靠性。

  3. 辅助医生决策:为医生提供客观的病变区域分析和分类结果,辅助制定治疗方案。

  4. 推动医疗普惠:通过智能化诊断系统,弥补偏远地区医疗资源的不足,让更多患者受益。


主要技术

  1. 模型选择:采用YOLOv10作为核心检测算法,因其在速度和精度上的优异表现,非常适合实时医学图像分析场景。

  2. 数据增强:对训练集进行数据增强(如旋转、缩放、翻转等),以提高模型的鲁棒性。

  3. 模型训练:使用训练集对YOLOv10模型进行训练,优化损失函数,提升检测精度。

  4. 模型评估:使用验证集和测试集评估模型的性能,计算mAP(平均精度均值)等指标,确保模型达到预期效果。

  5. 部署应用:将训练好的模型部署到医疗诊断设备或移动终端中,实现实时皮肤病检测。

目录

一、项目介绍

项目背景

项目意义

主要技术

二、项目功能展示

系统功能

图片检测

视频检测

摄像头实时检测

三、数据集介绍

数据集使用

数据集配置文件data.yaml

数据集制作流程

四、项目环境配置

创建虚拟环境

pycharm中配置anaconda

安装所需要库

五、模型训练

训练代码

训练结果

六、核心代码

七、项目源码(视频下方简介内)


基于深度学习YOLOv10的皮肤病识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv10的皮肤病识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

二、项目功能展示

系统功能

图片检测:可对图片进行检测,返回检测框及类别信息。

视频检测:支持视频文件输入,检测视频中每一帧的情况。

摄像头实时检测:连接USB 摄像头,实现实时监测。

参数实时调节(置信度和IoU阈值)

  • 图片检测

该功能允许用户通过单张图片进行目标检测。输入一张图片后,YOLO模型会实时分析图像,识别出其中的目标,并在图像中框出检测到的目标,输出带有目标框的图像。

  • 视频检测

视频检测功能允许用户将视频文件作为输入。YOLO模型将逐帧分析视频,并在每一帧中标记出检测到的目标。最终结果可以是带有目标框的视频文件或实时展示,适用于视频监控和分析等场景。

  • 摄像头实时检测

该功能支持通过连接摄像头进行实时目标检测。YOLO模型能够在摄像头拍摄的实时视频流中进行目标检测,实时识别并显示检测结果。此功能非常适用于安防监控、无人驾驶、智能交通等应用,提供即时反馈。

核心特点:

  • 高精度:基于YOLO模型,提供精确的目标检测能力,适用于不同类型的图像和视频。
  • 实时性:特别优化的算法使得实时目标检测成为可能,无论是在视频还是摄像头实时检测中,响应速度都非常快。
  • 批量处理:支持高效的批量图像和视频处理,适合大规模数据分析。

三、数据集介绍

类别数量(nc):7类
类别名称

  1. Bowen's Disease(鲍恩病)

  2. Basal Cell Carcinoma(基底细胞癌)

  3. Benign Keratosis Lesions(良性角化病变)

  4. Dermatofibroma(皮肤纤维瘤)

  5. Melanoma(黑色素瘤)

  6. Melanocytic Nevus(黑素细胞痣)

  7. Vascular Lesions(血管病变)

数据集特点

  1. 多样性:数据集中包含了多种不同类型的皮肤病,涵盖了从良性病变到恶性病变的多种情况。

  2. 复杂性:皮肤病的外观可能表现为颜色、纹理、形状的复杂变化,增加了检测的难度。

  3. 标注质量:每张图像都经过精确的标注,标注信息包括病变的类别和边界框(Bounding Box),确保模型训练的准确性。

  4. 场景真实性:数据集中的图像均来自真实的皮肤病诊断场景,能够很好地反映实际应用中的挑战。


数据集使用

  • 训练集:用于训练YOLOv10模型,通过大量的皮肤病图像数据,使模型能够学习到不同病变类型的特征。

  • 验证集:用于调整模型超参数,优化模型性能。

  • 测试集:用于最终评估模型的性能,验证模型在真实场景中的泛化能力。

数据集配置文件data.yaml

train: .\datasets\images\train val: .\datasets\images\val test: .\datasets\images\test nc: 7 names: ['Bowen‘s Disease', 'Basal Cell Carcinoma', 'Benign Keratosis Lesions ', 'Dermatofibroma', 'Melanoma', 'Melanocytic Nevus', 'Vascular Lesions']

数据集制作流程

  • 标注数据:使用标注工具(如LabelImg、CVAT等)对图像中的目标进行标注。每个目标需要标出边界框,并且标注类别。

  • 转换格式:将标注的数据转换为YOLO格式。YOLO标注格式为每行:<object-class> <x_center> <y_center> <width> <height>,这些坐标是相对于图像尺寸的比例。

  • 分割数据集:将数据集分为训练集、验证集和测试集,通常的比例是80%训练集、10%验证集和10%测试集。

  • 准备标签文件:为每张图片生成一个对应的标签文件,确保标签文件与图片的命名一致。

  • 调整图像尺寸:根据YOLO网络要求,统一调整所有图像的尺寸(如416x416或608x608)。

四、项目环境配置

创建虚拟环境

首先新建一个Anaconda环境,每个项目用不同的环境,这样项目中所用的依赖包互不干扰。

终端输入

conda create -n yolov10 python==3.9

激活虚拟环境

conda activate yolov10

安装cpu版本pytorch

pip install torch torchvision torchaudio

pycharm中配置anaconda

安装所需要库

pip install -r requirements.txt

五、模型训练

训练代码

from ultralytics import YOLOv10 model_path = 'yolov10s.pt' data_path = 'datasets/data.yaml' if __name__ == '__main__': model = YOLOv10(model_path) results = model.train(data=data_path, epochs=500, batch=64, device='0', workers=0, project='runs/detect', name='exp', )
根据实际情况更换模型 yolov10n.yaml (nano):轻量化模型,适合嵌入式设备,速度快但精度略低。 yolov10s.yaml (small):小模型,适合实时任务。 yolov10m.yaml (medium):中等大小模型,兼顾速度和精度。 yolov10b.yaml (base):基本版模型,适合大部分应用场景。 yolov10l.yaml (large):大型模型,适合对精度要求高的任务。
  • --batch 64:每批次64张图像。
  • --epochs 500:训练500轮。
  • --datasets/data.yaml:数据集配置文件。
  • --weights yolov10s.pt:初始化模型权重,yolov10s.pt是预训练的轻量级YOLO模型。

训练结果

六、核心代码

import sys import cv2 import numpy as np from PyQt5.QtWidgets import QApplication, QMessageBox, QFileDialog from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLOv10 from UiMain import UiMainWindow import time import os class DetectionThread(QThread): frame_received = pyqtSignal(np.ndarray, np.ndarray, list) # 原始帧, 检测帧, 检测结果 finished_signal = pyqtSignal() # 线程完成信号 def __init__(self, model, source, conf, iou, parent=None): super().__init__(parent) self.model = model self.source = source self.conf = conf self.iou = iou self.running = True def run(self): try: if isinstance(self.source, int) or self.source.endswith(('.mp4', '.avi', '.mov')): # 视频或摄像头 cap = cv2.VideoCapture(self.source) while self.running and cap.isOpened(): ret, frame = cap.read() if not ret: break # 保存原始帧 original_frame = frame.copy() # 检测 results = self.model(frame, conf=self.conf, iou=self.iou) annotated_frame = results[0].plot() # 提取检测结果 detections = [] for result in results: for box in result.boxes: class_id = int(box.cls) class_name = self.model.names[class_id] confidence = float(box.conf) x, y, w, h = box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) # 发送信号 self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) # 控制帧率 time.sleep(0.03) # 约30fps cap.release() else: # 图片 frame = cv2.imread(self.source) if frame is not None: original_frame = frame.copy() results = self.model(frame, conf=self.conf, iou=self.iou) annotated_frame = results[0].plot() # 提取检测结果 detections = [] for result in results: for box in result.boxes: class_id = int(box.cls) class_name = self.model.names[class_id] confidence = float(box.conf) x, y, w, h = box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) except Exception as e: print(f"Detection error: {e}") finally: self.finished_signal.emit() def stop(self): self.running = False class MainWindow(UiMainWindow): def __init__(self): super().__init__() # 初始化模型 self.model = None self.detection_thread = None self.current_image = None self.current_result = None self.video_writer = None self.is_camera_running = False self.is_video_running = False self.last_detection_result = None # 新增:保存最后一次检测结果 # 连接按钮信号 self.image_btn.clicked.connect(self.detect_image) self.video_btn.clicked.connect(self.detect_video) self.camera_btn.clicked.connect(self.detect_camera) self.stop_btn.clicked.connect(self.stop_detection) self.save_btn.clicked.connect(self.save_result) # 初始化模型 self.load_model() def load_model(self): try: model_name = self.model_combo.currentText() self.model = YOLOv10(f"{model_name}.pt") # 自动下载或加载本地模型 self.update_status(f"模型 {model_name} 加载成功") except Exception as e: QMessageBox.critical(self, "错误", f"模型加载失败: {str(e)}") self.update_status("模型加载失败") def detect_image(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return file_path, _ = QFileDialog.getOpenFileName( self, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png *.bmp)") if file_path: self.clear_results() self.current_image = cv2.imread(file_path) self.current_image = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB) self.display_image(self.original_image_label, self.current_image) # 创建检测线程 conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f"正在检测图片: {os.path.basename(file_path)}") def detect_video(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return file_path, _ = QFileDialog.getOpenFileName( self, "选择视频", "", "视频文件 (*.mp4 *.avi *.mov)") if file_path: self.clear_results() self.is_video_running = True # 初始化视频写入器 cap = cv2.VideoCapture(file_path) frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = cap.get(cv2.CAP_PROP_FPS) cap.release() # 创建保存路径 save_dir = "results" os.makedirs(save_dir, exist_ok=True) timestamp = time.strftime("%Y%m%d_%H%M%S") save_path = os.path.join(save_dir, f"result_{timestamp}.mp4") fourcc = cv2.VideoWriter_fourcc(*'mp4v') self.video_writer = cv2.VideoWriter(save_path, fourcc, fps, (frame_width, frame_height)) # 创建检测线程 conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f"正在检测视频: {os.path.basename(file_path)}") def detect_camera(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, "警告", "请先停止当前检测任务") return self.clear_results() self.is_camera_running = True # 创建检测线程 (默认使用摄像头0) conf = self.confidence_spinbox.value() iou = self.iou_spinbox.value() self.detection_thread = DetectionThread(self.model, 0, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status("正在从摄像头检测...") def stop_detection(self): if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread.quit() self.detection_thread.wait() if self.video_writer: self.video_writer.release() self.video_writer = None self.is_camera_running = False self.is_video_running = False self.update_status("检测已停止") def on_frame_received(self, original_frame, result_frame, detections): # 更新原始图像和结果图像 self.display_image(self.original_image_label, original_frame) self.display_image(self.result_image_label, result_frame) # 保存当前结果帧用于后续保存 self.last_detection_result = result_frame # 新增:保存检测结果 # 更新表格 self.clear_results() for class_name, confidence, x, y in detections: self.add_detection_result(class_name, confidence, x, y) # 保存视频帧 if self.video_writer: self.video_writer.write(cv2.cvtColor(result_frame, cv2.COLOR_RGB2BGR)) def on_detection_finished(self): if self.video_writer: self.video_writer.release() self.video_writer = None self.update_status("视频检测完成,结果已保存") elif self.is_camera_running: self.update_status("摄像头检测已停止") else: self.update_status("图片检测完成") def save_result(self): if not hasattr(self, 'last_detection_result') or self.last_detection_result is None: QMessageBox.warning(self, "警告", "没有可保存的检测结果") return save_dir = "results" os.makedirs(save_dir, exist_ok=True) timestamp = time.strftime("%Y%m%d_%H%M%S") if self.is_camera_running or self.is_video_running: # 保存当前帧为图片 save_path = os.path.join(save_dir, f"snapshot_{timestamp}.jpg") cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f"截图已保存: {save_path}") else: # 保存图片检测结果 save_path = os.path.join(save_dir, f"result_{timestamp}.jpg") cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f"检测结果已保存: {save_path}") def closeEvent(self, event): self.stop_detection() event.accept() if __name__ == "__main__": app = QApplication(sys.argv) # 设置应用程序样式 app.setStyle("Fusion") # 创建并显示主窗口 window = MainWindow() window.show() sys.exit(app.exec_())

七、项目源码(视频下方简介内)

完整全部资源文件(包括测试图片、视频,py文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:

基于深度学习YOLOv10的皮肤病识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv10的皮肤病识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

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

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

相关文章

基于深度学习的水稻病害检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍 项目背景&#xff1a; 水稻是全球最重要的粮食作物之一&#xff0c;但其生长过程中容易受到多种病害的侵袭&#xff0c;如Bacteria_Leaf_Blight&#xff08;细菌性叶枯病&#xff09;、Brown_Spot&#xff08;褐斑病&#xff09;、Leaf_smut&#xff08;叶黑粉病…

基于深度学习YOLOv10的小麦叶片病害检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍 项目背景&#xff1a; 小麦是全球重要的粮食作物之一&#xff0c;但其生长过程中容易受到多种病害的侵袭&#xff0c;如Powdery_Mildew&#xff08;白粉病&#xff09;、Septoria&#xff08;叶枯病&#xff09;、Stem_Rust&#xff08;秆锈病&#xff09;、Yell…

全国信誉好的带司机包车有哪些品牌推荐? - 工业品牌热点

随着企业商务活动、会务接待需求的持续增长,带司机包车服务已成为企业降本提效、保障出行体验的核心选择。本文聚焦带司机包车企业信誉好的带司机包车有名的带司机包车机构三大关键词,通过问答形式拆解企业选择带司机…

claude code MCP 安装范围

MCP 服务器可以在三个不同的范围级别进行配置,每个级别都用于管理服务器可访问性和共享的不同目的。本地范围:个人服务器、实验配置或特定于一个项目的敏感凭据 项目范围:团队共享的服务器、项目特定的工具或协作所…

想当高薪健身教练?2026 年靠谱培训机构推荐来了! - 品牌2025

随着健身行业专业化升级,市场对具备系统能力与权威认证的教练需求持续攀升。无论是零基础想入行的新人、寻求技能突破的在职教练,还是关注员工健康服务的企业从业者,选择一家合规、专业的培训机构成为关键。优质机构…

2026年评价高的酸雾塔喷淋塔,,环保喷淋塔厂家优质推荐名录 - 品牌鉴赏师

引言在环保意识日益增强的当下,酸雾塔喷淋塔等环保设备在工业废气治理领域发挥着至关重要的作用。为了给广大用户提供一份客观、公正、权威的酸雾塔喷淋塔厂家推荐名录,我们依据国内环保行业相关的权威数据和指南进行…

2026西宁市英语雅思培训辅导机构推荐、2026权威出国雅思课程排行榜 - 苏木2025

为精准解决西宁市城东区、城中区、城西区、城北区、湟中区、湟源县、大通回族土族自治县广大考生在雅思培训中的选课难题,权威教育测评机构联合雅思教研专家,结合本地考生需求与全国教学标准,开展了全面且深度的测评…

2026 年健身教练培训机构怎么选?这份避坑指南请收好! - 品牌2025

健身行业的蓬勃发展,让专业教练成为市场刚需,但选对培训机构是入行或进阶的关键。不少人因盲目选择踩坑,要么资质不正规导致证书无效,要么课程与市场脱节难以就业。为帮大家避开陷阱,本文结合资质、课程、师资等核…

计算机人网络安全兼职秘籍:凭技术接单赚外快的实用方法!

很多计算机人&#xff08;学生 / 转行从业者&#xff09;觉得 “网络安全兼职门槛高&#xff0c;必须是大神才能接”&#xff0c;其实不用会复杂渗透&#xff0c;只要掌握基础工具&#xff08;如 Nmap、Burp&#xff09;或简单编程&#xff0c;就能接 “50-5000 元” 的兼职单。…

2024年山东CSP-X复赛真题解析

​欢迎大家订阅我的专栏:算法题解:C++与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的…

2025年度优质钣金加工企业权威推荐,钣金加工排行解析品牌实力与甄选要点 - 品牌推荐师

在制造业智能化、精密化转型的浪潮下,钣金加工作为工业制造的基础环节,其技术水平与服务质量直接影响着下游装备的性能与外观。市场对具备高精度、高效率、一站式服务能力的钣金供应商需求日益旺盛。基于对行业公开数…

2026年真空干燥箱源头厂家技术与应用概况 - 品牌排行榜

真空干燥箱作为一种利用真空环境降低水沸点以实现低温干燥的设备,广泛应用于电子、半导体、生物医疗、新材料等领域,其性能直接影响产品质量与研发效率。源头厂家在设备的核心技术研发、生产工艺控制及定制化能力上具…

CTF 全方向入门指南:Crypto 到 Web 全覆盖,网络安全小白必看(建议收藏)

文章详细介绍了CTF竞赛的五大方向&#xff1a;Crypto密码学、Pwn二进制漏洞挖掘、Web安全、MISC杂项和逆向工程。每个方向阐述了其特点、优势、所需知识储备与工具准备&#xff0c;强调兴趣和坚持是学习关键。文章鼓励初学者不畏困难&#xff0c;通过实践逐步提升技能&#xff…

2026西宁市英语雅思培训辅导机构推荐,2026权威出国雅思课程排行榜 - 苏木2025

基于《2025年中国雅思考试白皮书》核心数据及第三方调研机构3000+西宁考生真实反馈,本次针对西宁市城东区、城中区、城西区、城北区、湟中区、大通回族土族自治县、湟源县全域考生需求,开展全面深度测评,结合雅思培…

导师推荐10个AI论文平台,自考毕业论文轻松搞定!

导师推荐10个AI论文平台&#xff0c;自考毕业论文轻松搞定&#xff01; AI 工具助力论文写作&#xff0c;轻松应对自考挑战 在自考论文写作过程中&#xff0c;许多学生常常面临选题困难、结构混乱、内容重复等问题。而随着 AI 技术的不断发展&#xff0c;越来越多的 AI 工具开始…

2026国内最新玻璃胶品牌top5评测,优质企业及厂家榜单发布,服务覆盖江苏、山东、云南、四川、广东、浙江等地,定义绿色家居建材新生态 - 品牌推荐2026

随着绿色环保理念深入人心,高性能玻璃胶成为家居装修、工程建设中保障安全与美观的关键材料。本榜单基于环保性能、产品多样性、技术创新力、服务覆盖度四大维度(绿康建材新增"全产业链整合"维度),结合行…

PHP vs Go:动态与静态的终极对决

语言类型与设计哲学PHP是一种动态类型、解释型脚本语言&#xff0c;主要用于Web开发&#xff0c;设计初衷是简化网页生成任务。语法灵活&#xff0c;适合快速开发中小型项目。Go&#xff08;Golang&#xff09;是一种静态类型、编译型语言&#xff0c;由Google设计&#xff0c;…

完整教程:tslib及QT移植

完整教程:tslib及QT移植pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &q…

Laravel vs ThinkPHP:项目选型终极指南

框架定位与适用场景Laravel适合中大型项目或复杂业务场景&#xff0c;提供完整的生态系统&#xff08;如Eloquent ORM、队列系统、测试工具等&#xff09;&#xff0c;遵循严格的设计模式&#xff08;如依赖注入&#xff09;。ThinkPHP更适合快速开发中小型项目&#xff0c;尤其…

2026年开年杭州可靠的智能猫砂盆平台推荐排行 - 2026年企业推荐榜

转载自:https://www.nicepp10.com/rankinglis/288613.html 文章摘要 随着“它经济”的蓬勃发展,智能猫砂盆已成为宠物消费升级的核心品类,尤其在杭州这类新一线城市,养宠家庭对科技化、健康化养宠方案的需求日益旺…