YOLOv8高空抛物检测项目全解析:从训练到可视化部署
简介基于YOLOv8目标检测模型的社区高空抛物监测系统是一套面向计算机视觉与深度学习方向毕业设计、课程设计的完整项目方案围绕社区高空抛物实时检测与可视化监控场景将模型训练、视频检测和可视化界面整合在一起按资源说明可输出核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果以及标签分布图适合支撑毕设答辩或课设演示。压缩包共8个文件包括3个Python脚本训练、检测和界面展示、3个pt权重文件可直接加载推理和2个txt文档项目结构与部署步骤整体约15.91MB轻量便于下载目前已有31人学习/下载。拿到资源后按README配置环境即可复现训练脚本可微调数据检测脚本可读取视频流执行识别可视化页面便于展示效果和图表对于需要快速完成毕业设计或课程设计的计算机相关专业学生这是一份拿来即用的高质量参考既能快速跑通流程也能在此基础上做二次改进。1. 社区高空抛物监测YOLOv8 目标检测落地的一个完整样本高空抛物被称为“悬在城市上空的痛”一个烟头、一个酒瓶从十几层扔下来动能相当惊人事后回溯责任时又往往因为摄像头看不清、找不到出处而不了了之。传统摄像头方案基本靠人盯在监控室效率和防御半径都很难让人满意。这个项目做了一件事用 YOLOv8 对社区监控画面做实时抛物检测检测到物体坠落轨迹时立刻截图标记、统计时间窗并生成一套供回溯的检测结果。对毕设或课程设计来说它最大的优势不是“模型多高深”而是完整——源码、可视化界面、真实场景数据集、训练脚本、部署说明全在一份压缩包里解压后按 README 走一遍就能跑出可演示的检测效果答辩现场可以直接打开可视化页面拉着视频溜一圈生成曲线图和混淆矩阵给评委看。项目本质是“目标检测 视频流处理 结果可视化”三板斧选型上用的是 YOLOv8 和配套的 yolo11n 预训练权重PySide 或 Tkinter 系的桌面可视化界面负责把检测结果变成人话。它能监控一段视频文件或实时画面把每一帧里属于“高空抛物”的目标框出来并记录下出现时间和置信度。对想拿它做毕设的人这套东西最值钱的不是算法创新而是“检测逻辑 界面 训练流程”互相打通——你可以直接改检测置信度、换数据集重新训练或者把视频检测改造成摄像头实时监测。本文会从目录结构、核心模块、训练流程、常见踩坑到二次开发思路把这套代码完整拆开讲。2. 源码结构与核心链路这套系统由哪些文件拼起来拿到压缩包先别急着跑第一步是看清目录里每个文件的职责。整个项目的骨架并不复杂由入口脚本、检测执行模块、模型训练模块、可视化页面脚本和数据集构成外加 README 和训练产物文件。2.1 文件清单与各模块作用解压后的根目录下核心文件大概是这么几个train_mode.py模型训练入口切换成训练模式时执行负责数据加载、YOLOv8 训练、验证集指标输出。Detection_video.py视频检测主脚本加载训练好的权重对视频帧做推理并在画面绘制检测框。Visual_interface.py可视化页面设计脚本用于把检测结果做桌面端展示启动图形界面。yolov8n.pt/yolo11n.ptYOLOv8 系列预训练权重前者是 n 型轻量级模型后者是 yolo11 的 n 规格。best.pt训练阶段产出的最优权重直接用于后续推理。README.txt部署和运行说明第一步应该打开的文件。从职责边界上看train_mode.py负责“练”Detection_video.py负责“用”Visual_interface.py负责“看”。这三个文件把深度学习项目里最容易混成一锅粥的工作拆成了三段改起来思路很清晰。值得注意的一个细节是压缩包里同时存在yolov8n.pt和best.pt。yolov8n.pt是官方预训练权重用于迁移学习或对比实验best.pt是本项目在自己的数据集上微调后选出的最佳权重。推理时如果有best.pt我一般会优先加载它因为它的识别精度通常高于纯粹靠 COCO 预训练的通用权重对社区抛物场景中的小物体更友好。2.2 检测流程的主链路拆解整套系统的运行可以用一条链路讲清楚加载模型权重 → 读取视频帧 → 对每一帧做预处理 → 送入 YOLOv8 网络推理 → 解析输出张量 → 过滤低置信度框 → 绘制检测框并标注类别 → 输出到屏幕或保存为结果视频。拿Detection_video.py来说它内部会调用 YOLO 接口对视频逐帧执行推理。这里的推理本质上走的是 YOLOv8 的model.predict(source帧数据, conf阈值, imgsz输入尺寸)流程。抛出一个 640x640 的预处理图像网络输出一个形状类似[batch, num_dets, 6]的结果张量其中最后一维的前四个是检测框坐标第五个是置信度第六个是类别编号。系统需要从里面挑出置信度大于阈值的框再用类别名称替换编号最后画框。高空抛物检测的特殊性在于它和通用目标检测有个显著差别待测目标很小、运动速度很快。一个从 20 楼扔下来的矿泉水瓶在画面里可能只占几个像素而且连续几帧之间的位移很大。这时候直接套用默认的 YOLOv8 参数容易漏检需要把检测置信度调低一点或者对输入帧做区域裁剪让模型在小物体上的分辨率更充分。这就是为什么代码里通常会有conf参数的位置调整它就能微妙地改变系统的灵敏度。# 这段伪代码展示 Detection_video.py 的核心推理逻辑 from ultralytics import YOLO # 加载最优权重/path/to/best.pt 替换为实际路径 model YOLO(/path/to/best.pt) # conf0.25 表示只保留置信度高于 0.25 的检测框 # imgsz640 表示输入推理尺寸为 640x640 results model.predict( source/path/to/test_video.mp4, conf0.25, imgsz640, saveTrue, # 保存检测结果视频 projectruns/detect, # 输出目录 nameexp_high_altitude # 本次运行的子目录 )这里的conf0.25是通用默认值放到高空抛物场景下我的习惯是先跑一遍看漏检率。如果画面里明明有物体下落但没画框就把conf往下调到 0.1 试试代价是误检多一些但至少不会错过关键事件。imgsz的默认 640 兼顾速度和精度如果显卡显存充足且需要检测更小的目标可以试着提到 960小物体的召回率会有可感知的上升。project和name两个参数决定输出目录跑完去runs/detect/exp_high_altitude/就能看到带检测框的视频这是后续写报告时最有力的素材。2.3 可视化页面的接入方式Visual_interface.py是这套系统能拿出去演示的关键。它提供的可视化页面不只是单纯展示画面还带有交互属性。页面上通常会设计一个“选择视频文件”按钮、一个显示区域和一个记录检测事件的面板。常见交互逻辑是点击加载视频 → 视频在显示区域播放 → YOLOv8 逐帧推理结果回传到界面 → 检测到目标时显示区域边缘变红或弹出事件记录行 → 同时把当前帧截图保存到本地。# Visual_interface.py 中典型的检测结果回传逻辑 def update_frame(self): # 从视频流中读取一帧 ret, frame self.cap.read() if not ret: return # 将当前帧送入 YOLO 模型得到检测结果 results self.model(frame, verboseFalse) # 提取检测到的目标数量 boxes results[0].boxes if len(boxes) 0: # 在界面上提示检测到抛物并记录事件 self.event_log.append(检测到目标置信度最高为 {:.2f}.format( float(boxes.conf.max()) )) # 保存截图逻辑 self.save_snapshot(frame)这里面有个很容易踩的坑视频播放线程和界面更新线程如果没做好分离画面一卡一卡检测框还会延迟。常见做法是在子线程里做模型推理推理完成后再通过信号或回调把结果抛回主线程更新界面。update_frame里的results[0].boxes.conf.max()用于取当前帧所有目标里的最高置信度作为界面提示的参考数值。这段逻辑说明可视化页面并不是想象中那么玄真正的工作量在“线程调度”和“事件传递”上模型推理本身几行代码就完事。3. 核心模块拆解YOLOv8 训练的完整链路与评估体系训练是这套系统的另一个重头戏。社区场景没有现成的公开高空抛物数据集可用常见的做法是自己收集社区监控片段逐帧标注目标或者用已知的开源抛物数据集做迁移学习。这个项目的train_mode.py承担的就是这个从数据到模型的流程。3.1 训练脚本的工作流程train_mode.py的核心逻辑不复杂但涉及的数据流程值得拆开看。脚本按 YOLOv8 的规范要求需要准备一个 YAML 格式的数据配置文件里面写清楚训练集和验证集路径、类别数量以及类别名称。一个典型的数据配置文件high_altitude_data.yaml大概是这样的train: ./dataset/train/images val: ./dataset/val/images nc: 1 names: [falling_object]训练脚本调用方式大致如下from ultralytics import YOLO # 以 yolov8n.pt 作为基础权重做迁移学习 model YOLO(yolov8n.pt) # 在自有数据集上微调 100 轮 model.train( datahigh_altitude_data.yaml, epochs100, imgsz640, batch16, devicecpu, # 无 GPU 时用 CPU有 GPU 改成 0 patience20, # 连续 20 轮验证指标不提升就早停 projectruns/train, namehigh_altitude_exp )train_mode.py中大概率存在类似的参数配置段只是把超参数以变量形式定义在脚本头部便于直接修改。这里的epochs100表示模型会遍历训练集 100 次batch16是每次迭代喂给模型的图片数patience20是早停策略模型在验证集上连续 20 轮没有提升就自动结束训练避免过拟合。device参数是血泪经验最多的地方如果显卡显存不足batch需要相应调小否则直接 OOM训练中断。训练完成后runs/train/high_altitude_exp/目录下会生成一堆产物包括best.pt、last.pt、args.yaml、confusion_matrix.png、results.png、F1_curve.png、PR_curve.png等。best.pt是验证集上指标最好的权重文件后续视频检测用的就是它。results.png里面包含 train/loss、val/loss、mAP50、mAP50-95 随 epoch 变化的曲线这是答辩时直接截到论文里的标准配图。3.2 关键评估指标图还能怎么用压缩包摘要里特别提到“可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图”。这些图在毕设答辩里的作用是实打实的每一项都对应着模型在不同维度上的表现混淆矩阵展示模型把“抛物目标”识别成什么、漏检了哪些、有没有把背景误判成目标。社区场景里最容易出现的是误检——飞鸟、树叶、塑料袋都可能被框成抛物混淆矩阵能让你直观看到误检集中在哪一类。F1 分数曲线本质上是精确率和召回率的调和平均展示在不同置信度阈值下 F1 的变化。F1 曲线的峰值点对应的置信度阈值就是你在推理时可以设置的最优conf。如果曲线峰值不高说明模型还没训好需要检查数据标注质量或增加训练轮数。精确率-召回率曲线PR 曲线PR 曲线越靠近右上角说明模型性能越好。对于类别极不平衡的高空抛物场景PR 曲线比 mAP 更能反映真实表现因为正样本数量少光看准确率会虚高。标签分布图展示训练集中每个类别出现的次数。如果“falling_object”只有几百个标签模型很难收敛到高精度此时要么补充数据要么把场景拆成更粗粒度的类别。换句话说训练完不是看一眼 loss 降了就完事应该打开results.png确认 val loss 曲线没有在后期抬升打开confusion_matrix.png看模型有没有把太多背景当目标。如果发现误检严重回到数据集去修正标注或者考虑做背景负样本增强。3.3 训练质量的直观判断方法跑完训练拿到一堆曲线图怎么快速判断模型能不能用我用的是三看策略。一看results.png中的 val/box_loss 曲线它应当随着 epoch 增加而下降并且训练后期趋于平缓。如果验证损失曲线在训练后期拐头向上说明模型开始过拟合这时就应该停早停参数patience就是为了防止这种情况。二看验证集预测结果图它通常是一张带标签和检测框的真实画面如果验证图上的检测框能大致包住目标物体且置信度高于 0.5这模型基本能达到演示水准。三看 PR 曲线重点关注曲线下面积 AP如果 AP 值在 0.8 以上说明模型在查准率和查全率之间平衡得不错如果 AP 只有 0.6需要在数据预处理或训练超参数上进一步调整。复核素材和源码清单高空抛物监测系统的实现程度如何# 危险操作把这份资源讲成「功能先讲清、再能跑起来、最后能上手改」的项目解析文。4. 环境配置与运行部署从零到跑通检测的完整流程读完源码结构必然要上手跑。这套系统依赖 Python 环境、PyTorch 和 ultralytics 库以及配套的 GUI 库和 OpenCV。4.1 环境准备与依赖安装项目没有额外提供 requirements.txt 的明确信息但按照 YOLOv8 跑视频检测的标准配置需要装的核心依赖如下pip install ultralytics pip install opencv-python pip install numpyultralytics是 YOLOv8 和 yolo11 的官方实现库装好后自带 YOLO 类能省掉大量重复代码。opencv-python负责视频帧读取、图像预处理、画框以及结果视频的编码输出。numpy是图像矩阵操作的基础OpenCV 读入的帧本质上是 numpy 数组。如果是跑Visual_interface.py可视化页面还需要确认桌面 GUI 库是否已安装。常见的可能是 PySide6 或 tkinter其中 tkinter 是 Python 自带库无需额外安装PySide6 需要单独装pip install PySide6在跑之前建议先验证一下 GPU 环境。如果电脑没有 NVIDIA 显卡或没装 CUDA模型会落到 CPU 推理速度会慢一些但不影响功能。视频检测场景下 CPU 也能跑只是帧率偏低。用以下命令可以快速确认模型能不能正常加载python -c from ultralytics import YOLO; model YOLO(best.pt); print(模型加载成功)这条命令的作用是让 ultralytics 库读取权重文件结构并创建网络。如果输出“模型加载成功”说明环境依赖没问题如果报错显示缺少某个模块按报错信息补装即可。这里的环境问题一半以上都出在 ultralytics 和 PyTorch 版本不匹配上补装的时候建议优先关注这两个库的版本号。4.2 视频检测模式怎么跑环境没问题后运行视频检测是最直观的验证方式。用命令行直接执行python Detection_video.py --source test_video.mp4 --weights best.pt --conf 0.25这段命令将指定输入视频文件和权重文件然后输出检测结果视频。如果不习惯命令行传参有一种更直接的方式很多 YOLOv8 项目会干脆把Detection_video.py写成可独立执行脚本在文件底部留一个if __name__ __main__:入口参数写死在脚本里直接python Detection_video.py就行。不管采用哪种方式输出结果会在runs/detect/目录下生成一个带检测框的视频文件。建议运行前先准备一段 10 秒以上的社区监控样片画面里最好有从楼上落下的物体。如果手头没有真实抛物视频也可以人工做一个模拟场景——从阳台扔个小纸团或塑料瓶用手机横向录制再转成 MP4 格式。YOLOv8 对这类视频能做到十几到几十帧每秒的推理速度一次运行通常在几十秒内完成。失败时的排查思路如果跑视频检测时控制台报错九成原因出在权重文件路径或输入视频路径不对。best.pt和视频文件要放在项目根目录或者用绝对路径。另一个常见错误是视频编码格式不兼容OpenCV 对某些 H.265 编码的监控视频会读不出帧换成 H.264 编码或 MP4 格式基本能解决。4.3 可视化页面如何启动视频检测跑通后可视化页面是第二个验证节点。运行命令python Visual_interface.py启动后页面出现点击选择视频加载刚才的测试视频然后开始检测。和命令行模式相比可视化页面的优势在于实时反馈——检测到抛物时界面上不仅有框还有事件记录和截图。这个页面在毕设答辩时可以现场操作比放录屏更有说服力。可视化页面跑不通时先看控制台有没有报“ModuleNotFoundError”如果有根据提示安装缺失库。如果库都装了但页面空白检查视频文件的路径是否正确有些页面实现会默认读取固定目录需要把视频放在指定位置。还有一种翻车场景是界面打开后一加载视频就卡死这通常是推理线程没有和 UI 线程分离导致的。后面会专门聊怎么改这块代码。4.4 数据集与目录结构说明训练数据集的存放结构决定了train_mode.py能否正常读取。标准结构如下dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ └── high_altitude_data.yamlimages目录存放图片labels目录存放同名的 txt 标注文件每行格式为class x_center y_center width height归一化到 0~1 之间。如果数据集是你自己标注的注意标注文件的类别索引必须从 0 开始否则模型训练时的类别映射会错乱。项目自带的数据集在压缩包内部解压后应检查它的目录结构是否和这个规范一致。如果发现数据集中有图片缺失、标注文件损坏的情况训练会直接报错排查速度最快的方法是写一段小脚本遍历labels目录检查每个 txt 文件是否和图片文件名一一对应。5. 避坑指南高空抛物检测项目的高频翻车点排查这套系统虽然“拿来就能跑”但真跑起来时各种翻车现场还是层出不穷。下面几条是实操中最容易踩到的坑按“现象 → 原因 → 解决”的方式展开。5.1 模型加载成功但检测不出任何目标现象模型加载正常视频也能播放但画面上从头到尾没出现一个框控制台也没有报错。常见原因是置信度阈值设太高。高空抛物目标小、运动模糊、在画面中的占比通常低于 5%模型输出的置信度普遍偏低。如果沿用默认的 0.25 甚至更高的阈值大部分帧都会被过滤掉。解决方式把conf参数下调到 0.1~0.15提高模型召回率。同时检查输入视频的分辨率和码率如果视频分辨率过低目标可能只有几个像素模型根本没法识别。我一般会先把imgsz提到 960 做一次推理如果效果明显提升说明是分辨率瓶颈可以考虑对监控画面做分区域检测。5.2 训练时报错 “AssertionError: Label class is out of range”现象跑train_mode.py时训练在数据加载阶段就报错提示某个标签文件的类别索引超出范围。原因通常是数据集标注文件里写了类别1但 YAML 配置文件里nc只设了 1类别索引最大只能为 0。当数据集中有多个类别而 YAML 只声明了一个类别时训练脚本会拒绝加载。解决方式检查high_altitude_data.yaml中的nc是否和标注文件里的最大类别编号 1 一致。要么修改 YAML 中的类别数量要么用脚本批量把标注文件里的类别编号统一改成 0。检查命令很简单在终端执行for f in dataset/train/labels/*.txt; do awk {print $1} $f; done | sort -u这条命令会列出所有标签文件里出现的类别编号看到什么编号就去 YAML 里把nc改成“最大编号 1”。如果只有一个类别字段统一改成 0 即可。5.3 可视化页面卡死或无法刷新现象Visual_interface.py启动后点击加载视频窗口立刻无响应转几圈后系统提示“程序未响应”。原因是视频读取和模型推理都在 UI 主线程里执行推理一帧要几百毫秒几秒后界面线程被阻塞系统判定程序挂死。解决方式把视频循环和推理逻辑全部移入独立线程UI 主线程只负责接收检测结果并刷新画面。常见做法是使用QThread或者threading.Thread。如果不想动大工程还可以在推理循环里手动调用刷新函数强制界面重绘但效果远不如线程分离来得干净。后面一章会给出线程改造的具体示例。5.4 CPU 推理太慢视频播放像幻灯片现象检测结果正确但处理速度极慢一段 10 秒的视频要好几分钟才处理完基本没法做实时预览。原因大概率是设备没有 GPU 或模型推理没走 GPU。如果电脑确实有 NVIDIA 显卡但 ultralytics 默认没用上需要检查 CUDA 版本和 PyTorch 的 CUDA 构建是否匹配。解决方式先执行python -c import torch; print(torch.cuda.is_available())如果输出False说明 PyTorch 不是 CUDA 版本需要重新安装对应 CUDA 版本的 PyTorch 包。如果输出True在训练脚本里显式指定device0即可让模型跑在 GPU 上。当然如果电脑没有独立显卡那只能接受 CPU 推理的现实建议把输入视频分辨率压缩后再做检测速度会有明显提升代价是目标变糊需要权衡。6. 二次开发思路把毕设改成可落地的智能监控方案代码跑通只是第一步。对毕设来说从“能跑”到“能讲”中间差一个“自己动手改过”的痕迹。下面几个方向是最容易操作、也最能体现工作量加成的。6.1 改造推理线程让可视化页面不卡死第一个推荐改造点就是把视频推理搬到子线程。这块改动不复杂收益却是“答辩现场流畅演示”和“卡死重启”的差别。核心思路是新建一个QThread子类在run()方法里循环读取视频帧、执行推理通过信号把帧数据和检测结果发送给主界面。# worker_thread.py 子线程推理示例 from PySide6.QtCore import QThread, Signal import cv2 class DetectionThread(QThread): frame_ready Signal(object, object) # 发射检测框和帧数据 def __init__(self, model, video_path, conf0.25): super().__init__() self.model model self.video_path video_path self.conf conf self.running True def run(self): cap cv2.VideoCapture(self.video_path) while self.running and cap.isOpened(): ret, frame cap.read() if not ret: break # 推理verboseFalse 关闭多余日志输出 results self.model.predict(frame, confself.conf, verboseFalse) boxes results[0].boxes self.frame_ready.emit(frame, boxes) cap.release()改完后UI 线程通过frame_ready信号接收数据并刷新画面不会再有卡死问题。这里的Signal(object, object)是线程安全的信号机制object类型用于传递任意 Python 对象实际使用时传帧的 numpy 数组和检测框对象。running标志位用于窗口关闭时停止线程避免后台继续跑推理消耗 CPU。6.2 换模型对比yolo11n 是否更优项目压缩包里同时提供了yolo11n.pt和yolov8n.pt这其实是很好的实验素材。yolo11n是 YOLO 系列迭代的产物理论上在同等体积下有小幅精度提升。二次开发时可以写一个对比实验脚本固定同一段测试视频分别加载两个权重统计各自的平均检测置信度、检测框数量和推理耗时。# compare_models.py 对比实验脚本思路 import time from ultralytics import YOLO models { yolov8n: YOLO(yolov8n.pt), yolo11n: YOLO(yolo11n.pt) } for name, model in models.items(): start time.time() results model.predict(test_video.mp4, conf0.2) elapsed time.time() - start total_boxes sum(len(r.boxes) for r in results) print(f{name}: 处理耗时 {elapsed:.2f}s检测框总数 {total_boxes})跑完对比把表格放进论文“实验设计”部分就是一个小有说服力的对比实验。不用额外改动模型代码只需在训练脚本里将model YOLO(yolov8n.pt)换成model YOLO(yolo11n.pt)就能完成一次完整的模型替换训练。这个操作对新手足够友好对熟手也能引出“不同 Backbone 对高空抛物小目标检测的影响”这种论文切入点。6.3 数据增强与误检优化方向高空抛物检测的根本难点在于小目标和背景干扰。二次开发时最容易见效的优化方向是数据增强——在训练配置中增加随机旋转、缩放、亮度扰动、马赛克增强等操作。比如对抛物场景同一物体在强光、阴影、傍晚等光照条件下的表现差异极大通过亮度扰动可以把模型的鲁棒性拉起来。# 在训练脚本中增加数据增强参数 model.train( datahigh_altitude_data.yaml, epochs100, imgsz640, batch16, augmentTrue, # 开启 YOLOv8 内建增强 mosaic1.0, # 马赛克增强强度 mixup0.1, # 混合样本增强 fliplr0.5, # 随机水平翻转 )注意mosaic1.0表示每一步训练时每个 batch 都会做马赛克增强但对小目标检测有利有弊——马赛克会改变物体在原图中的位置分布如果目标太小拼接后可能更难识别。实践中建议先设 0.5 试跑对照看验证集 mAP 的变化。如果加了增强后 mAP 反而下降说明当前数据集规模和场景亮度分布已经足够或者目标太小不适合强数据增强。这类“调参 观察 判断”的过程恰恰是最能在答辩中讲出彩的部分。6.4 扩展真实监控场景的注意事项把视频检测扩展成摄像头实时监测时路径配置和推流参数会有些变化但这套系统的核心代码其实不用大改。YOLOv8 的model.predict可以直接接收摄像头设备号或 RTSP 流地址。需要注意的不只是推理速度还有事件存储策略——抛物目标通常只出现零点几秒你需要一个环形缓冲区保存最近 5 秒的视频帧检测到目标时把前后几秒的片段一起落盘这样才能保留完整的抛物轨迹。从这个角度看项目从“完成毕设”到“落地真实社区”中间还差一个事件存储模块但源码的检测和可视化部分可以直接复用。就好比从一套演示 Demo 变成一套可用系统核心算法反而不是门槛工程化和场景适配才是。从那以后我每次接手这类检测项目都会强制自己先跑一遍原始视频检查漏检再调阈值最后才动代码——这顺序省了我不少无用功。希望帮到你。本文还有配套的精品资源点击获取