简介:这是一套基于YOLOv8的车牌识别系统项目包,面向具备一定Python与深度学习基础的开发者、算法工程师及计算机视觉学习者。系统覆盖车牌检测、字符分割与识别全流程,内置轻量级预训练模型yolov8n.pt,可用于实时摄像头识别与批量图片处理,并提供了数据库管理、Web界面交互等模块,便于工程化落地与二次开发。
压缩包共61个文件,大小6.36MB,以Python脚本为主(37个py文件),同时包含配置(yaml/yml/toml/ini)、说明(md/txt)、模型(pt)与示例图片(jpg)等,目录划分清晰,主程序入口、识别逻辑、工具函数与系统配置相互分离,方便按需调用与调试。
已有95人浏览学习,适合作为实战参考。资源中不仅能直接运行车牌识别主流程,还包含实时处理、批处理、配置管理和Web展示等脚本,结合预训练模型可快速验证效果,对理解YOLOv8在具体场景中的应用落地有直接帮助。
1. YOLOv8 车牌识别系统:不只是“检测到车牌”这么简单
刚接触“基于YOLOv8的车牌识别系统.zip”这个项目包的人,容易把它想成“用 YOLOv8 训练一个模型,输入图片,输出车牌号”这么一步到位。实际上手你会很快发现,这里藏着一个明显的分界:YOLOv8 在其中的角色是检测——从画面里把“车牌区域”这个目标框出来,而真正把框里的图像变成一串可读的字符(比如“京A12345”),是另一套 OCR 识别逻辑负责的。很多新手在这个衔接点上翻车,以为模型输出里直接带着字符串,结果发现只有坐标框。
这个项目包解决的核心诉求很实际:给一段监控视频或一张道路照片,系统能自动锁定车牌位置、裁出车牌图像、再识别出牌号,把结果实时叠加到画面上。适合做毕业设计、安防岗亭的离线识别演示、停车场出入口的原型验证,或者作为你入门“检测 + 后续处理”这类复合任务的练手项目。它的边界也很清楚:针对的是蓝底白字车牌这一类常规场景,对新能源绿牌、黄牌大车、倾斜畸变严重的车牌,需要额外数据支撑。
我把这类项目拆成四条主线:环境怎么搭、数据怎么备、模型怎么训、识别怎么接。下面按这个顺序把每一步的参数、命令和坑位都交代清楚。
2. 从零搭建 YOLOv8 环境:CPU 版与 GPU 版的取舍
2.1 Python 虚拟环境与依赖安装
这个项目包最常见的运行形态是 YOLOv8 检测 + OpenCV/OCR 后处理,所以环境准备集中在 Python 侧。我一般习惯用 conda 建独立环境,避免跟系统自带的 Python 打架。
# 创建 python 3.9 环境,避免直接用系统 python conda create -n plate python=3.9 -y conda activate plate # 安装 PyTorch CPU 版本,约 200MB 左右,适合无独立显卡的机器 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # 安装 ultralytics 库,这是 yolov8 的官方实现入口 pip install ultralytics # 后续处理常用依赖 pip install opencv-python pillow numpy逻辑说明:这里先装 PyTorch 再装 ultralytics,是因为 ultralytics 运行时要调用 torch 作为后端,如果先装 ultralytics,它会自动拉一个默认的 CUDA 版 torch,在没显卡的机器上白白占掉几个 GB。用--index-url指定 CPU 源是常见做法,能精确控制 torch 版本。
参数说明:Python 3.9 是目前兼容性最稳的选择。3.10 以上能用,但 opencv 和部分 OCR 库的预编译轮子偶尔会缺;3.8 以下则面临 torch 新版不支持的问题。CPU 版本推理时,一张 640x640 的图片大约耗时 200~500ms,做实时视频流会吃力,静态图片和离线视频完全够用。
2.2 预设权重下载与首次推理验证
环境装完后,先跑一句推理验证整个链路通不通,再动数据集。
# 下载 yolov8n.pt 预设权重并测试一张图 yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg' # 查看检测结果 ls runs/detect/predict/这段命令的意思:yolo predict是 ultralytics 提供的一行式预测入口,model=yolov8n.pt指定用 nano 版本权重(约 6MB,CPU 上速度最快),source可以是图片 URL、本地图片路径或视频文件。第一次运行时权重会自动下载到当前目录,之后不再重复下载。
参数说明:yolov8n是 YOLOv8 系列里最小的模型,mAP 相对低但推理速度最快,适合先在 CPU 机器上验证流程。如果你的项目包里带的是yolov8s.pt或yolov8m.pt,说明原项目倾向精度优先,那你后续训练时的 batch size 要相应调小,否则显存或内存容易爆掉。
提示:如果
yolo命令找不到,先检查是否pip install ultralytics成功后当前 shell 没有重载,执行python -m ultralytics也能触发相同逻辑。
3. 车牌数据集准备:从标注到 YOLO 格式转换
3.1 数据来源与标注要求
想要让车牌识别系统真正能在自己的场景里跑出效果,最省力的是拿项目包里已标注好的数据集做增量训练,但如果你手头只有一堆车牌照片,需要自己处理一遍标注。
常见做法是:收集 3000~5000 张包含车牌的车头正面照片,用 LabelImg 或 Labelme 框出车牌矩形区域,标注类别名统一为plate。这里要注意,目标检测阶段的标签是“车牌”这一个类,不是“京A12345”的逐字符标签;字符识别是后面单独一步。很多新手在这里把类别标成了每个数字和汉字,导致训练出来的模型又慢又乱。
标注完的 XML/JSON 文件需要转换成 YOLO 需要的 txt 格式,每行内容为:类别id 中心点x 中心点y 宽度 高度。转换脚本在项目包里很常见,我直接给出核心逻辑:
import os import xml.etree.ElementTree as ET from glob import glob def convert_xml_to_yolo(xml_path, out_dir, class_map={'plate': 0}): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find('size/width').text) img_h = int(root.find('size/height').text) out_lines = [] for obj in root.iter('object'): name = obj.find('name').text if name not in class_map: continue box = obj.find('bndbox') xmin = int(box.find('xmin').text) ymin = int(box.find('ymin').text) xmax = int(box.find('xmax').text) ymax = int(box.find('ymax').text) # 转换为 yolo 相对坐标 x_center = (xmin + xmax) / 2.0 / img_w y_center = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h out_lines.append(f"{class_map[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}") out_name = os.path.basename(xml_path).replace('.xml', '.txt') with open(os.path.join(out_dir, out_name), 'w') as f: f.write('\n'.join(out_lines)) # 批量转换 for xml_file in glob('annotations/*.xml'): convert_xml_to_yolo(xml_file, 'labels/')逻辑说明:这段代码的核心是把 XML 里的绝对像素坐标转换成 YOLO 要求的相对坐标。除数分别是图片宽度和高度,保证转换后的数值落在 0~1 区间。
参数说明:class_map里的类别映射必须和后续训练配置文件data.yaml中的类别顺序一致,否则模型学到的序号和实际含义会错位。这里只定义plate一个类,但如果你的项目包中识别部分是在检测阶段直接输出字符类别,那 class_map 需要按字符集展开,常见的有省份汉字 31 个、字母 24 个(避开 I/O)、数字 10 个。
3.2 数据集划分与目录结构
训练前需要把图片和标签按比例分成 train、val 两个集合,常见比例是 8:2,测试集可以后续从 val 中临时抽。目录结构按 YOLO 惯例如下:
datasets/ plate/ images/ train/ val/ labels/ train/ val/同时准备一个data.yaml,内容如下:
# 数据集配置文件,路径使用相对项目根的路径 path: datasets/plate train: images/train val: images/val nc: 1 names: ['plate']参数说明:path字段是数据集根目录,train 和 val 的路径是相对path的。nc是类别数,这里只有车牌一个类所以是 1。如果你的项目包里原带了data.yaml,优先在它基础上改路径,因为其中可能隐藏了一些原作者的预处理细节,比如已经做过去重和清洗。
3.3 数据增强策略:别乱加,只在需要时开
YOLOv8 默认自带 Mosaic、随机仿射等增强,但对于车牌这种形状高度规整的目标,默认的随机裁剪旋转可能让车牌变成不可识别的角度。我一般会这样控制:保留hsv_h(色调变化)模拟不同光照,关闭degrees或限制在 ±10 度内,关闭fliplr或保持开启(因为车牌文字左右翻转后识别阶段需要额外处理)。
# 在训练命令中直接指定增强参数 yolo detect train \ data=datasets/plate/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ degrees=5 \ hsv_h=0.02 \ fliplr=0.0参数说明:degrees=5表示训练时图片随机旋转不超过 5 度,模拟车辆略微倾斜的拍摄角度,同时又不至于让车牌上的字符形变过大。fliplr=0.0表示关闭水平翻转,因为车牌“京A”水平翻转后变成“A京”,识别模型会学到错误特征。hsv_h=0.02给色调一个很小的扰动范围,应对早晚阳光色温变化。
4. 模型训练与调参:把通用检测器变成车牌检测器
4.1 训练启动与损失曲线观察
数据集就位后,启动训练。训练过程的监控主要看两个指标:box_loss是否持续下降、val/accuracy或mAP50是否在后期仍缓慢上升。
yolo detect train \ data=datasets/plate/data.yaml \ model=yolov8n.pt \ epochs=150 \ imgsz=640 \ batch=16 \ device=cpu \ project=plate_train \ name=exp1如果机器有 NVIDIA 显卡,把device=cpu改成device=0,训练速度能提升 10~20 倍;没有显卡就老老实实 CPU 跑,150 轮的数据量如果 3000 张,CPU 大约 6~10 小时可以完成。
参数说明:imgsz=640是训练输入尺寸。车牌本身在画面中通常偏小,如果监控画面中车牌像素宽度低于 60px,建议把 imgsz 提高到 960 或 1280,代价是显存占用翻倍、训练时间变长。batch=16是根据 CPU 内存 16GB 设定的,显存 8GB 的 GPU 建议用 32,显存 12GB 以上可以尝试 64,batch 太小会导致 BN 层统计不稳定。
4.2 训练参数含义与调整策略
YOLOv8 训练命令中几个参数的实质影响值得说透:
epochs:不是越大越好。当 val 损失连续 30 轮不下降时,后续训练只是在过拟合训练集。我一般设置 150,同时开启早停patience=30。optimizer:默认是auto,会自动选 AdamW 或 SGD。对于小数据集,SGD 收敛更稳,AdamW 前期下降快但末期容易在小数据集上波动。cos_lr=True:学习率按余弦曲线衰减,实验结果普遍比阶梯式下降好 2~3 个点 mAP,但训练时长不变。cache=True:把图片预先缓存到内存,CPU 训练时能省去反复读取磁盘的时间。如果内存只有 8GB 且数据集超过 2000 张,别开,会直接内存溢出。
yolo detect train \ data=datasets/plate/data.yaml \ model=yolov8s.pt \ epochs=150 \ imgsz=640 \ batch=32 \ optimizer='SGD' \ cos_lr=True \ patience=30 \ cache=True逻辑说明:这里把模型从yolov8n换成了yolov8s,因为 n 版本在车牌这类小目标上的精度偏低,s 版本在保持实时性的前提下 mAP50 通常能高 5~8 个点,代价是模型大小从 6MB 涨到 22MB,CPU 推理单帧耗时约增加 50%。对离线视频处理项目,这个代价完全值得。
4.3 训练结果评估与典型问题
训练结束后,重点检查runs/detect/exp1/weights/best.pt和last.pt。best 是验证集上表现最好的权重,last 是最后一轮的权重,通常 last 的 mAP 略低但泛化性偶尔更好。
评估命令:
# 在验证集上评估 best.pt yolo detect val \ model=plate_train/exp1/weights/best.pt \ data=datasets/plate/data.yaml输出中重点看mAP50和mAP50-95。如果一个车牌检测项目 mAP50 低于 0.9,基本说明数据集质量有问题或者训练没收敛。先检查 labels 目录里的txt文件是否有空文件、坐标值是否超出 0~1 区间,这两类错误占训练翻车原因的八成。
5. 车牌识别后处理与集成:检测框到可读字符串的最后一公里
5.1 检测结果输出接口
YOLOv8 模型本身返回的是boxes对象,包含坐标、置信度和类别。要把检测结果接给识别模块,常见做法是遍历预测结果,将每个车牌的框裁出来:
from ultralytics import YOLO import cv2 model = YOLO('plate_train/exp1/weights/best.pt') img = cv2.imread('test_car.jpg') results = model.predict(img, conf=0.45, imgsz=640, verbose=False) for result in results: boxes = result.boxes for box in boxes: x1, y1, x2, y2 = box.xyxy[0].tolist() conf = box.conf[0].item() if conf < 0.45: continue # 裁出车牌区域,留 5% 边距让字符完整落入 h, w = img.shape[:2] pad_x = (x2 - x1) * 0.05 pad_y = (y2 - y1) * 0.05 x1 = max(0, int(x1 - pad_x)) y1 = max(0, int(y1 - pad_y)) x2 = min(w, int(x2 + pad_x)) y2 = min(h, int(y2 + pad_y)) plate_crop = img[y1:y2, x1:x2] cv2.imwrite(f'plate_{conf:.2f}.jpg', plate_crop)参数说明:conf=0.45是置信度阈值,可以理解为“模型有多大把握认为这是车牌”。低于这个值的一律丢弃。实际场景里,0.35 以下误检概率陡增,0.6 以上会漏掉模糊车牌,0.45 是均衡点。边距pad_x/pad_y给 5% 的原因是:字符紧贴车牌边缘时,检测框偶尔会切掉半个字符。
5.2 车牌字符识别:OCR 环节的两种接法
第一步的检测模型只能给出“车牌在哪”,字符串的识别通常有两种常见路径:
第一种:接 PaddleOCR 或 Tesseract 这类通用 OCR,直接对裁剪图做端到端识别。优点是省事,缺点是通用 OCR 对蓝底白字的反白字符、汉字识别率大约只有 80%~90%,需要二次校正。
第二种:单独训练一个字符分类/序列识别模型,比如把裁剪图按字符宽度切分成单字符图片,再用一个分类模型逐个识别。这是传统车牌识别项目包最常见的方式,因为字符集固定(31 个省份汉字 + 24 个字母 + 10 个数字),单字符分类模型的准确率可以稳定在 99% 以上。
# 字符切分示例:固定车牌为 7 个字符,按比例切分 plate_crop_gray = cv2.cvtColor(plate_crop, cv2.COLOR_BGR2GRAY) # 车牌宽高比通常约 3.14:1,第一个字符是汉字,位置偏左 char_h, char_w = plate_crop_gray.shape[:2] char_width_unit = char_w / 7.0 chars = [] for i in range(7): if i == 0: # 汉字比数字宽,单独调整切分范围 x_start = int(char_width_unit * 0.1) x_end = int(char_width_unit * 1.1) else: x_start = int(char_width_unit * i + char_width_unit * 0.05) x_end = int(char_width_unit * (i + 1) + char_width_unit * 0.05) chars.append(plate_crop_gray[:, x_start:x_end])这段切分逻辑依赖一个前提:车牌图像是正对摄像头的,没有明显透视畸变。如果实际场景中车辆斜停、转弯,切分前需要先做透视校正,否则字符边界会对不准。
提示:监控场景下很多车牌识别失败不是模型问题,而是检测框截取到了“车牌的上下边缘阴影”,导致 OCR 输入图像里字符和背景对比度下降。可以在切分前对裁剪图做一次自适应直方图均衡化(CLAHE),常见做法是用
cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))增强对比度。
5.3 完整识别链路串联
把检测和识别串成一条 pipeline,做成一个类,是项目包落地的关键。我一般建议写成模块,而不是把所有逻辑堆在一个脚本里:
class PlateRecognizer: def __init__(self, det_weight='best.pt', clf_weight='char_cls.pt'): self.detector = YOLO(det_weight) self.clf = YOLO(clf_weight) # 字符分类重用 YOLO 的 classify 能力 def recognize(self, img_path): results = self.detector.predict(img_path, conf=0.45) plates = [] for result in results: for box in result.boxes: x1, y1, x2, y2 = [int(v) for v in box.xyxy[0].tolist()] crop = img_path # 实际用 cv2 裁图 plate_str = self._ocr_plate(crop) plates.append((box.xyxy[0].tolist(), plate_str, box.conf[0].item())) return plates参数说明:char_cls.pt是独立的字符分类模型权重,输入是单字符图片,输出是 65 类(31 汉字 + 24 字母 + 10 数字)的 one-hot 向量。注意省份汉字里没有“I”和“O”这两个字母,字母集是 24 个。
6. 常见问题排查:车牌识别系统翻车的 5 个高频原因
6.1 现象:训练时 loss 不降或直接 NaN
原因:最常见是标签文件坐标越界或为负值。检查labels目录下是否有形如1.0234 0.5678 0.4562 0.7891这种 x 中心点大于 1 的异常数据,以及是否有空 txt 文件和对应的空图片。
解决:写一个小脚本扫描全部标签文件,过滤掉坐标不在 0~1 区间的样本,并删掉对应图片。另一个诱因是学习率过大,YOLOv8 默认 lr0=0.01,小数据集上可以降到 0.005 起步。
6.2 现象:检测框总是比车牌大一圈或小一圈
原因:标注框边缘贴得太紧或太松。YOLO 的回归目标包含边框交点,如果标注时框沿比车牌实际边缘宽出超过 10 个像素,模型学到的框天然偏大。
解决:重新检查标注是否有系统性偏差。常见做法是用一个 5px 的规则——标注时框边距离车牌边缘约 2~5 像素,既保证字符完整,又不会把旁边车身的纹理圈入负样本。
6.3 现象:识别结果第一个汉字经常错
原因:车牌的第一个字符是省份简称,像“京”“津”“冀”“苏”“浙”等汉字笔画密度差异大,而切分时汉字位置通常与后续字符宽度不一致,导致汉字被切半或被相邻字符挤占。
解决:汉字单独做一次宽度估计。常见做法是以第二到第七个字符的平均宽度作为基准,汉字宽度取 1.2 倍,起点从 x=0 开始而不是从单位宽度开始。如果项目包里已经带了汉字修正逻辑,检查它是否默认假设汉字宽度是数字的 1.1 倍,换用 1.2 倍后多数场景识别率有提升。
6.4 现象:夜间/阴天场景漏检严重
原因:训练数据里白天正光样本占大多数,模型学到的是“蓝色底 + 白色文字”的强对比度特征,夜间车灯照射下反光强烈或整体偏暗时,特征响应不足。
解决:数据增强里把hsv_s(饱和度)扰动范围加大到原来的两倍,让模型适应低饱和度画面;同时收集 20%~30% 的夜间样本,夜间样本在总数据集中的比例不要超过一半,否则白天场景开始翻车。
6.5 现象:视频流推理卡顿
原因:CPU 推理单帧 300ms,视频流 25fps 要求 40ms/帧,性能差了一个量级。
解决:两条路。一条是把 imgsz 从 640 降到 416,mAP 损失约 3~5 个点,速度提升约 60%;另一条是跳帧推理,每 3 帧推一次、中间两帧沿用上一次检测结果,车牌在视频流中连续帧变化很小,这个办法对监控场景非常实用。如果条件允许,换成rk3588这类边缘 NPU 设备部署是更好的出路,YOLOv8 的 ONNX 导出接口原生支持该平台的 RKNN 转换流程,但这是另一个大话题了。
7. 模型导出与部署进阶:把离线系统变成可交付的 .pt / .onnx 产物
7.1 导出 ONNX:摆脱 Python 环境依赖
训练完的项目包如果只是自己在本地跑,问题不大。但如果你想交付给别人——对方机器上不一定有 Python、不一定装得齐依赖——ONNX 导出是第一张后悔药:
# 导出 ONNX 格式,开启动态尺寸输入 yolo export model=plate_train/exp1/weights/best.pt format=onnx dynamic=True # 导出后可以看到 best.onnx 生成 ls -lh plate_train/exp1/weights/动态尺寸输入允许推理时传入任意尺寸图片,而不用固定 640。要注意的是 ONNX 推理需要onnxruntime,如果部署目标机的 CPU 支持 AVX 指令集但内存只有 2GB,推荐用onnxruntime的精简版,体积从 200MB 小到 50MB 左右。
7.2 量化:模型缩小一半,精度察觉不出
车牌识别项目部署到嵌入式设备时,模型体积和内存占用往往比精度更敏感。常见做法是把导出后的 ONNX 做 INT8 量化:
# 使用 onnxruntime 的量化工具,动态量化最简单 python -m onnxruntime.quantization \ --input best.onnx \ --output best_int8.onnx \ --quantize dynamic参数说明:动态量化不需要校准数据,压缩后模型体积约为原来的四分之一,但推理速度提升有限;静态量化需要准备 200 张代表性图片做校准,速度提升明显,但车牌夜晚样本多时校准集别漏了夜间的图片,否则白天晚上表现不一致。
提示:如果你最终跑在 RK3588 上,量化不是在 ONNX 层面做,而是 ONNX 转 RKNN 时用
rknn-toolkit2的build()接口完成,板上推理才吃 INT8 红利。这一步项目包里如果没有预置脚本,去查你手上开发板的 SDK 版本,不同 RKNN 版本支持的算子集有差异。
7.3 输出设计的最后一块:把结果写回业务
识别结果要落地,最终要能写进数据库或对接业务系统。我一般习惯给输出结构加一个时间戳和置信度,便于复盘:
import json from datetime import datetime def format_output(plate_str, conf, bbox, img_id): return { "plate": plate_str, "confidence": round(float(conf), 4), "bbox": bbox, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "image_id": img_id } # 用法示例 record = format_output("京A12345", 0.92, [102, 340, 212, 360], "cam01_000123") with open("records.jsonl", "a") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n")输出到 JSONL 方便后续排查;想要集成数据库,把这个字典直接传给 SQLAlchemy 模型或 pymysql 的批量插入接口都可以。车牌字符里的汉字编码要注意ensure_ascii=False,否则写进数据库的是\u4eac这类 Unicode 转义,排查数据时会绕远路。
8. 训练迭代策略:别把 best.pt 当终点
8.1 第二次训练的关键改动
拿到项目包里的预训练结果只是起点。我一般会用它跑一次自己的测试集,把识别错的图片单独抽出来,人工看一下究竟是检测漏了、还是 OCR 错了。这一步决定了第二次训练的方向:
# 把测试集里检测错误的结果单独导出,集中分析 yolo detect predict \ model=plate_train/exp1/weights/best.pt \ source=test_fail_images/ \ save_txt=True \ save_conf=True \ project=fail_analysis保存的 txt 里每行是类别、坐标和置信度。打开看图片,如果模型把“车牌”和“车标”混淆,说明数据里需要补充大量车头正面不带车牌的负样本;如果集中在某些特定光线,说明增强参数里对应扰动范围不够。
8.2 负样本的价值与采集
目标检测一个常被忽略的点是:负样本(没有目标的背景图)对精度的贡献不亚于正样本。车牌检测场景中,我一般会保留 20% 的负样本比例,直接从监控视频里抽没有车的空路面帧即可。在data.yaml的train子目录里放一部分不含目标的图片,YOLOv8 会自动把它们当背景样本参与训练,降低误检率。
关键是这批负样本必须贴近期望部署场景:如果最终要放停车场出口,负样本用出口道闸附近的视角采集;用高速公路的图片反而帮不上忙。
8.3 判断何时该换更大模型
yolov8n和yolov8s都跑完 150 轮后,对比 mAP 和单帧耗时的交叉收益。如果 mAP50 提升超过了 3 个点,而你的部署机器推理时延还扛得住,就值得继续试yolov8m;如果提升不到 1 个点,问题大概率不在模型容量,而在数据标注质量。这个判断能省掉大量盲目调参的时间。
我第一次做车牌识别项目时,就是迷信“大模型更准”,直接上了yolov8x,结果 CPU 上单帧推理 3 秒多,项目根本没法交付,后来回头检查才发现标注数据里有近三百张的坐标偏移,清洗之后用yolov8n效果反而更好。这类经验现在已经成为我每次开工前必查的三件事:标签坐标是否越界、类别映射是否对齐、正负样本比例是否失衡。希望帮到你。
本文还有配套的精品资源,点击获取