简介一套面向本科毕业设计的车牌识别系统实现方案以Python 3.7.3与OpenCV 4.0.0.21为主要技术栈结合Numpy、Tkinter、PIL完成图像处理、GUI界面与字符识别流程。内容按原始图像、预处理、车牌定位、字符分割、字符识别等模块组织覆盖传统图像处理与SVM字符分类思路适合计算机视觉方向学生作为课程设计或毕业论文参考。资源共48个文件主要包含jpg/png测试图片、py源码、7z训练数据集、dat模型文件以及README说明等类型压缩包约28.8MB目录结构含main_VLPR.py、img_recognition.py、svm.dat、svmchinese.dat等关键文件便于按模块阅读和复现。已有257人学习/下载对于入门车牌识别、理解OpenCV工程落地和毕业设计代码组织具有直接参考价值。压缩包内同时包括字符训练集与模型文件可快速体验从图像输入到车牌结果输出的完整链路减少环境配置与数据准备成本。1. 车牌识别系统在做什么从停车场的照片到一行车牌号停车场出口那根抬杆的背后摄像头对准车头从画面里把蓝色车牌框出来再把“京A12345”这一串字符逐字读出来——整个过程就是pythonOpencv车牌识别系统要解决的问题。网上关于车牌识别系统的代码不少但很多下载下来跑不通坏就坏在定位和分割环节没有把图像预处理做扎实。它的核心价值在于不依赖深度学习框架和GPU只用OpenCV的常规图像处理手段就能在普通笔记本上跑通“输入图片、输出车牌号”的完整闭环。适合毕业设计选它的人通常是想低成本验证一个系统工程同时给论文留下充足的优化空间。2. 系统架构与运行环境pythonOpencv能跑通的最小闭环2.1 为什么毕设选Opencv而不直接上深度学习毕业设计不是项目比赛老师真正看的是你懂不懂“为什么这样做”。纯深度学习的车牌识别是一个端到端黑匣子输入图片直接吐字符串中间过程没法拆解答辩时老师追问一句“定位失败是什么原因”很难答得扎实。而pythonOpencv这套传统图像处理方案能拆成三个清晰的环节车牌定位、字符分割、字符识别。每一个环节都有中间结果可以截图论文里的系统框图、算法流程图、实验对比都能填得满。从工作量来说深度学习方案还要牵扯数据集标注、模型训练、GPU租用整套流程跑完至少多花两周时间。而OpenCV方案不需要标注数据字符模板可以自己用画图工具生成也可以从公开车牌图上截取成本低且全部离线运行。预算有限的场景下这个方案是性价比最高的。如果你后续还想继续做研究这套方案也不是死路。定位模块后面可以换成YOLOv8分割和识别模块再接入轻量CNN论文的“后续工作与展望”一节也有现成素材。我个人见过不少把传统方案和深度学习结合来做毕设的同学答辩效果普遍比单一方案要好。2.2 系统四个模块怎么分工数据流怎么走一个完整的车牌识别系统数据流大致是这样的原始图像进入预处理模块做去噪和增强增强后的图像交给定位模块输出车牌位置的矩形框定位框裁出来的小图进入分割模块拆成单个字符最后每个字符图送到识别模块拼出最终车牌字符串。模块之间用标准图像格式传递任何一个环节替换掉都不影响其他模块。我用表格把这四个模块的核心内容列出来写论文时你也能直接引用模块输入输出主要方法图像预处理原始BGR图片增强后的BGR图片高斯滤波、直方图均衡化车牌定位增强后的图片车牌ROI区域坐标HSV色彩筛选、形态学运算、轮廓检测字符分割车牌ROI图片单个字符的灰度图列表灰度化、二值化、投影法字符识别单个字符图字符序列如 京A12345模板匹配或Tesseract OCR很多人会把预处理模块和省掉直接拿原图做定位这在光照均匀的实验图里没问题但一到室外照片就翻车。预处理模块我一般至少保留一步高斯滤波用一个5x5的核把传感器噪点压下去能让后面的HSV颜色筛选干净不少。主流程的代码骨架也很简单下面这个函数可以作为整个系统的入口import cv2 def recognize_plate(img_path: str) - str | None: # 读图并做基础预处理 img cv2.imread(img_path) if img is None: return None # 预处理高斯滤波后两个参数分别是核大小和标准差 blurred cv2.GaussianBlur(img, (5, 5), 0) # 定位车牌区域返回 (x, y, w, h) box locate_plate(blurred) if box is None: return None x, y, w, h box roi img[y:y h, x:x w] # 分割字符返回字符灰度图列表 char_imgs split_chars(normalize_plate_roi(roi)) # 逐个识别并拼接结果 result .join(match_template(c) for c in char_imgs) return result这个函数把后面几章要实现的方法全部串起来了。设计上有一个值得注意的点每个模块函数的输入输出都约定成OpenCV的numpy数组接口清晰后面你想单独测试某个环节只需在中间插一行cv2.imwrite就能看到那个阶段的图像。2.3 环境配置pycharm与vscode里装cv2的常见坑环境这块是初学者最容易卡住的地方也是热搜里提问最多的一环。先说标准操作在python安装教程里Windows下建议直接装Python 3.8到3.10之间的版本安装时记得勾选“Add Python to PATH”否则后面pip命令全都找不到。装完python后用管理员身份打开命令行执行以下命令# 安装opencv的python发行版cv2模块就是它提供的 py -3.10 -m pip install opencv-python # numpy是图像数组运算的基础通常会被自动带上 py -3.10 -m pip install numpy提示安装时如果提示pip 不是内部或外部命令说明Python的Scripts目录没有加入PATH去环境变量里补上C:\Users\你的用户名\AppData\Local\Programs\Python\Python310\Scripts即可。安装完成后验证是否成功python -c import cv2; print(cv2.__version__)能打印出版本号说明环境就绪。很多人在这步报ModuleNotFoundError: No module named cv2十有八九是解释器选错了。pycharm配置python环境时右下角选择解释器要确认选中的是刚才装好opencv的那个Python。vscode也一样按CtrlShiftP调出命令面板选择“Python: Select Interpreter”指向同一个解释器。还有个高频场景是Anaconda Prompt里面没有opencv因为在conda的base环境里执行pip和你pycharm里选用的解释器不是同一个。解决方法是把pycharm的项目解释器换成conda环境或者在Anaconda Prompt里执行conda install opencv-python保持环境同步。Python环境问题有很强的“玄学”色彩很多时候重装一遍pycharm解释器配置就好了。我的习惯是每新建一个项目就先执行一遍验证命令确认import cv2正常再开始写代码别等写了100行才暴露问题。3. 车牌定位用HSV颜色筛选加形态学处理把蓝色框找出来3.1 为什么定位要先转HSV而不是直接用BGROpencv读取出来的图片是BGR三通道直接判断像素“是不是蓝色”需要同时比较三个通道的大小关系比如b 100 and b r 30 and g 200这种写法。它的问题是受光照影响非常大同一块车牌在阴影里和正午阳光下BGR值能差出三四倍。而HSV色彩空间把色相、饱和度、亮度拆开了其中H通道代表颜色本质只要物体颜色不变H值基本稳定。所以第一步是把BGR图像转换到HSV空间然后划定蓝色车牌的颜色区间。标准做法是这样的import cv2 import numpy as np def locate_plate(img): # 转HSVH是色相S是饱和度V是明度 hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 蓝色车牌的HSV区间H在100~124之间 lower_blue np.array([100, 43, 46]) upper_blue np.array([124, 255, 255]) # inRange输出二值掩膜符合条件的像素为255其余为0 mask cv2.inRange(hsv, lower_blue, upper_blue) # 闭运算先膨胀再腐蚀把字符之间的空白连成一块 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (15, 5)) mask cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # 找外轮廓并返回候选区域 contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) candidates [] for cnt in contours: area cv2.contourArea(cnt) x, y, w, h cv2.boundingRect(cnt) aspect w / h # 面积和宽高比双重筛选 if 2000 area img.shape[0] * img.shape[1] * 0.3: if 2.0 aspect 6.0 and h 20 and w 80: candidates.append((x, y, w, h)) if not candidates: return None # 返回面积最大的候选框通常最像车牌 return max(candidates, keylambda b: b[2] * b[3])这段代码的核心逻辑分三步颜色筛选、形态学连接、轮廓筛选。cv2.inRange生成的是黑白掩膜蓝色区域被标记为白色。但字符之间有间隔掩膜可能是一块一块的零碎区域所以用闭运算把横向邻近的碎片连成一个整体。形态学核的大小是这里调试最频繁的参数核太平字符断开的区域连不上核太宽车身的蓝色拉花也被吞进来后面就得靠面积筛选兜底。3.2 定位主流程颜色掩膜、闭运算、轮廓提取定位这一步的结果直接决定后面识别环节能否工作。定位偏了一点分割出来的字符就是残缺的。为了提升定位成功率我一般会在轮廓筛选之前先做一次面积预筛。上面的代码里有两个关键判断一个是area必须小于整张图的30%防止镜头前恰好出现一整块蓝色广告牌被当成车牌另一个是宽高比在2.0到6.0之间因为标准燃油车牌比例是440:140约等于3.14但照片里车牌会因拍摄角度而发生透视变形所以留出余量。如果你要识别的是绿牌新能源车把HSV区间换成绿色的值即可# 绿色车牌H通道大约在35~77之间 lower_green np.array([35, 43, 46]) upper_green np.array([77, 255, 255])这个替换逻辑可以做成配置文件项运行时通过参数切换识别蓝牌还是绿牌答辩时也算一个功能亮点。颜色定位最怕的背景干扰有两个晴朗天气的蓝天、蓝色车身。蓝天干扰通常出现在画面上半部分一个讨巧的过滤办法是只保留图像下三分之二的区域作为搜索范围。蓝色车身的干扰则要靠后续的轮廓填充度过滤这部分我在第5章避坑里会详细展开。3.3 轮廓筛选的三个参数面积、宽高比和矩形填充度轮廓筛选是定位环节的“临门一脚”参数选得好不好决定误检率高不高。我总结了三个最值得调的参数直接给出一张参数速查表参数名建议取值范围作用调参方向最小面积2000~5000过滤噪点和远处小物体图片分辨率高就调大防止把噪点当车牌宽高比2.0~6.0锁定横向矩形结构先按3.14设定再按实际照片角度放宽矩形填充度0.4~0.8过滤不规则轮廓车身贴纸填充度低车牌填充度相对高矩形填充度rect_fill contourArea / (w * h)它衡量的是轮廓与其外接矩形的贴合程度。车牌是一个规则矩形轮廓面积接近外接矩形面积填充度通常在0.5以上而车身拉花形状不规则填充度偏低。加上这个判断的代码很简单for cnt in contours: area cv2.contourArea(cnt) x, y, w, h cv2.boundingRect(cnt) rect_fill area / (w * h) if rect_fill 0.4: continue # 轮廓不方正大概率不是车牌这个参数是我觉得传统Opencv方案里性价比最高的一行代码它能解决大量背景误检问题。实际调参时不要固定死某一组数字先在一张典型图片上跑把候选框用cv2.rectangle画出来再根据误检情况放宽或收紧。我用过最笨也最有效的办法就是收集二十张光照不同的测试图把这套参数跑一遍统计哪些图丢了车牌、哪些图多出了框再反向调整。4. 字符分割与识别从二值化到模板匹配的一条龙流程4.1 分割预处理二值化和去边框定位出来的ROI不仅仅是蓝色区域还包含车牌的白边框、铆钉等干扰物。直接对这个图做投影分割边框会被误判成一个很宽的字符块。所以第一步是向内收缩裁掉边框再转灰度做二值化def normalize_plate_roi(plate_bgr): # 取ROI的尺寸向内收缩去掉车牌边框 h, w plate_bgr.shape[:2] # 上下各裁掉15%左右各裁掉8%避开白边和铆钉 inner plate_bgr[int(h * 0.15):int(h * 0.85), int(w * 0.08):int(w * 0.92)] # 转灰度再做Otsu自适应二值化 gray cv2.cvtColor(inner, cv2.COLOR_BGR2GRAY) # THRESH_BINARY会把白色字符保留为白色蓝底变成黑色 _, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) return binary这里有一个初学者经常翻车的地方固定阈值cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)看着简单但光照一变就废。Otsu方法会自动计算最佳阈值不需要人为指定对不同光照的适应性要好得多。我在毕业设计里用的是THRESH_BINARY THRESH_OTSU的组合既做了二值化又让阈值自动适配。裁边的比例不要乱给。上下裁15%是因为车牌上下边框相对较窄左右裁8%是因为车牌左右边框更窄且有圆角。如果车牌本身倾斜这一步裁出来可能带一点画面临角后面用投影分割时会体现出来。4.2 投影法切分字符水平投影定上下垂直投影定左右投影法的原理很直观二值图中白色字符像素在每一列都有分布统计每列的白色像素数量字符区域会出现“有值、无值、有值”的交替排列。无值的列就是字符间隔根据这个边界就能把字符切开。import numpy as np def split_chars(binary): # 垂直投影统计每一列的白色像素数量 col_sum np.sum(binary, axis0) // 255 # 标记有内容的列 col_flag (col_sum 0).astype(np.int8) # diff找上升沿和下降沿分别对应字符开始和结束 edges np.diff(col_flag) starts np.where(edges 1)[0] ends np.where(edges -1)[0] # 处理字符贴边的边界情况 if len(starts) len(ends) - 1: starts np.insert(starts, 0, 0) if len(ends) len(starts) - 1: ends np.append(ends, len(col_flag) - 1) chars [] for s, e in zip(starts, ends): width e - s # 宽度太窄的片段多数是铆钉或噪点直接丢掉 if width 10: continue chars.append(binary[:, s:e]) return chars这段代码的关键点是np.diff的用法。col_flag是从0变为1的地方代表字符开始从1变为0的地方代表字符结束。第一个字符如果紧贴左边缘col_flag的开头就是1np.diff不会产生上升沿这时需要手动把0当作起点末尾同理。我在代码里用两个if把这两个边界情况补上了。宽度阈值width 10不是一个固定值它依赖车牌图片的实际尺寸。一个标准车牌ROI经过裁边后大约360像素宽平均每个字符宽度约60像素10到20像素的噪声块可以安全过滤。如果你用的是新能源绿牌字符增加到8个这个阈值适当下调到8更稳妥。投影法有一个天然弱点如果一个字符内部被中间的黑洞分割成两段垂直投影会把它切碎。常见于汉字“津”“皖”这些内部结构复杂、笔画稀疏的字符里。缓解办法是先做一次膨胀把字符内部的纤细间隙填上再投影分割。4.3 模板匹配识别汉字、字母、数字的批量比对字符分割得到的是若干个灰度小图识别环节要把它们归成具体的字符。最常见的做法是模板匹配把每个字符和事先准备好的标准字符图做相似度计算取相似度最高的作为结果。import os from glob import glob def match_template(char_img, templates_dirchars): # 统一尺寸避免字符大小不一致影响匹配 char_std cv2.resize(char_img, (20, 40)) best_score -1 best_char # 遍历模板文件夹下的每个字符子目录 for char_name in os.listdir(templates_dir): char_dir os.path.join(templates_dir, char_name) # 每个字符准备多张不同字体的模板 for tpl_path in glob(os.path.join(char_dir, *.png)): tpl cv2.imread(tpl_path, cv2.IMREAD_GRAYSCALE) tpl_std cv2.resize(tpl, (20, 40)) # TM_CCOEFF_NORMED对亮度变化不敏感 score cv2.matchTemplate(char_std, tpl_std, cv2.TM_CCOEFF_NORMED)[0][0] if score best_score: best_score score best_char char_name return best_char, best_score模板匹配说白了就是模板和待识别的字符逐像素对齐算相关性。TM_CCOEFF_NORMED是所有OpenCV匹配算法里对光照变化最稳的一个它先减均值再算归一化相关系数阈值可以在0.5到0.8之间取舍低于阈值的认为没有匹配上。模板库的拼装是一个体力活也是个细致活。汉字部分建议每个字符至少收集粗细不同的三种字体因为真实车牌上的汉字笔画宽度会随着材质磨损、反光程度变化。字母和数字相对简单但要注意“0”和“O”、“1”和“I”这两对长得像的字符形状极其接近时匹配分数很容易互相干扰。我的做法是在最后拼接结果的时候加一道正则校验import re # 中国车牌格式首位汉字、第二位字母、后面五位字母数字 pattern r^[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][A-Z][A-Z0-9]{5}$ if re.fullmatch(pattern, result): print(识别结果合理:, result) else: print(结果异常需要人工复核:, result)这条正则虽然简单却是提高系统可靠性的一个高性价比手段。车牌识别不是每个字符独立判定的车牌本身有固定的字符规则用这个规则去做全局纠错能把单字符识别错误滤掉一大半。比如第二位结果识别成了数字正则直接判定异常此时可以选择降低置信度阈值或输出“无法识别”。5. 避坑光照反光、车贴干扰、车牌倾斜的排查记录5.1 案例一反光导致车牌区域直接定位不到现象正午阳光下白色字符边缘的蓝色被强光打成了灰白色inRange掩膜里车牌区域变成一片碎裂的白点轮廓面积不够定位模块返回None。原因HSV的V通道代表明度。过曝后车牌蓝色区域的V值逼近255S饱和度掉到很低直接超出了预设的HSV区间。颜色判断最怕的是“颜色被白光冲掉”蓝色不再是蓝色而成了白色。解决在定位之前加一层反光兜底判断。如果整图的V通道均值过高先对原图做整体压暗和对比度拉伸把过曝区域拉回正常范围。具体做法是计算HSV里V通道的均值超过阈值就对BGR图做一次convertScaleAbshsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) avg_v hsv[:, :, 2].mean() if avg_v 200: # alpha是对比度倍数beta是亮度偏移这里选择整体压暗 img cv2.convertScaleAbs(img, alpha0.8, beta-40)这个办法的原理是通过降低亮度偏移来恢复蓝颜色。实际测试中发现压暗后再重新做HSV转换蓝色车牌的H值几乎不变而S值会回到正常区间。不过这也提醒一个经验不要试图用一组HSV阈值通吃所有光照环境留一个光照估计的前置步骤会让整个系统稳得多。5.2 案例二车身广告被当成车牌误检框四处乱跳现象一张车身贴了蓝色拉花或“魔兽”风格贴纸的图片定位模块返回了三个候选框没有一个框住真正的车牌。原因颜色筛选只看HSV区间而车身贴纸的面积可能比车牌还大轮廓的宽高比恰好落在2到6之间。单一条件筛选就是把误检放进来。解决增加矩形填充度约束同时在候选区域内部做二次验证。所谓二次验证就是检查候选框内部是否包含足够多的字符像素——车牌区域二值化后白色像素比例明显高于普通车身贴纸# 候选框内部再做一次内容验证 def verify_candidate(img, box): x, y, w, h box roi img[y:y h, x:x w] gray cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) # 统计灰度大于200的像素占比车牌字符通常有5%左右白点 ratio np.sum(gray 200) / (w * h) # 纯色车贴或广告白色像素占比往往很低 return ratio 0.04这里的0.04只是一个经验初值。你可以在自己整理的数据集上统计一下车牌区域和背景区域的白色像素占比分布画个折线图就一目了然。这种小验证逻辑写在论文里很有说服力因为它体现了“系统不是只靠一个参数打天下而是多级筛选联合决策”的思想。注意调试定位问题时优先在找轮廓之后把候选框画出来保存到本地再决定是放宽还是收紧条件。盲调参数非常容易来回“翻车”耽误半天都不知道改了什么。5.3 案例三车牌装歪了分割出来的字符是斜的现象前视角拍摄的图片车牌在画面中有30度左右的旋转分割模块切出来的字符带着明显的倾角识别结果前两位连续出错。原因投影法默认字符是水平排列、上下边缘对齐的。车牌旋转后行方向的投影不再落在同一水平带内字符左右两端高低错位切出来的图是歪的。解决在定位后立即做透视校正。用cv2.minAreaRect取得外接旋转矩形得到倾角再通过仿射变换把车牌旋转到水平def straighten_plate(plate_img, contour): # minAreaRect返回旋转矩形的中心、尺寸、旋转角 rect cv2.minAreaRect(contour) angle rect[2] # OpenCV的角度范围是[-90, 0]超过45度需要换算 if angle 45 or angle -45: angle 0 h, w plate_img.shape[:2] center (w // 2, h // 2) M cv2.getRotationMatrix2D(center, angle, 1.0) return cv2.warpAffine(plate_img, M, (w, h))这里有一个非常坑的细节cv2.minAreaRect返回的旋转角横排矩形在接近水平时是0度稍微左倾是负值右倾是正值。我调试时发现当车牌接近垂直时角度会跳到接近90度所以加了判断超过正负45度就强制归零避免转了个大圈。校正以后再做投影分割字符就是规整的了。这个步骤对识别准确率的提升是肉眼可见的尤其对于不习惯把摄像头装正的停车场场景几乎是必加的一步。5.4 调试经验把每一步中间结果存成图再找问题做图像处理项目最忌讳的就是把整个流程跑完只看最后输出中间任何一步错了都没法定位。我在做这套系统时养成了一个习惯在每个模块的出口加一段调试存图代码def debug_save(prefix, img): os.makedirs(debug, exist_okTrue) cv2.imwrite(fdebug/{prefix}.png, img)在定位掩膜、闭运算结果、二值化结果、每个分割字符处分别调用debug_save。这样排查问题时直接把debug文件夹里的图按编号排一遍就能看出哪一步坏了。比如分割出来的字符如果全都是歪的问题在倾斜校正如果只有一半字符问题在垂直投影的宽度阈值如果字符有但识别全错问题在模板库。这个习惯让我避开了很多无谓的调参也让我在答辩展示时有很好的过程截图材料。这也印证了一句话在视觉系统里中间结果就是最好的调试日志。6. 从单张照片到批量验证一张表看清识别系统的真实准确率毕业设计最后阶段老师一定会问“你的系统准确率是多少”。只有一个样例截图拿不出手你需要一个批量验证脚本。我的做法是准备一个测试图像目录每张图片的文件名就是它的标准答案例如京A12345.jpg脚本自动遍历目录并统计正确率import os import cv2 def batch_evaluate(img_dir): total correct 0 error_cases [] for fname in sorted(os.listdir(img_dir)): if not fname.endswith((.jpg, .png)): continue # 文件名去掉扩展名就是标准车牌号 gt_label os.path.splitext(fname)[0] # 调用主识别流程 pred recognize_plate(os.path.join(img_dir, fname)) total 1 if pred gt_label: correct 1 else: # 记录错误案例后面人工分析错误原因 error_cases.append((fname, gt_label, pred)) print(f总样本数: {total}) print(f识别正确: {correct}) print(f总体准确率: {correct / total * 100:.2f}%) for case in error_cases: print(f错误: 文件名{case[0]}, 期望{case[1]}, 实测{case[2]})有了这个脚本你就可以在论文里放一张“不同场景下识别准确率对比表”比如白天、夜晚、雨天、倾斜车牌各20张统计结果后分析每种场景的失败原因。这些失败案例不是论文的减分项反而是你做了充分实验的证明。我当时测试了100张图片准确率87%把错误分成三类定位失败、分割失败、识别失败分别给出原因这个分析框架就是论文里最好用的一个章节。随着实验数据的积累你会发现传统Opencv方案的瓶颈最后都会指向光照变化和字符粘连这时候再去调研深度学习的车牌识别方案理解为什么卷积网络能提升鲁棒性就会比直接上手更透彻。我也犯过一个低级错误一开始把所有模板直接放在一张大图上匹配结果永远识别不对。后来才明白每个模板必须单独保存成图片尺寸统一到和测试字符一致。这种问题如果不做批量验证根本发现不了。后来我给自己定了个规矩改任何参数都同步记录到配置文件里试过哪组参数失败了就在注释里标上失败原因保证同一个坑不踩第二次。最后给你一个更省事的做法如果时间紧张识别环节可以直接接Tesseract的OCR引擎虽然对汉字车牌的准确率不如精心调过的模板匹配但胜在部署简单。把模板匹配和OCR两个方案的准确率都跑一遍对比表放进论文反而显得你做了方案选型。希望帮到你。本文还有配套的精品资源点击获取