OpenCV-Python实战:从环境搭建到人脸检测与车牌识别
在计算机视觉和图像处理领域OpenCV 是一个无法绕开的开源库。无论你是想从零开始学习图像处理还是需要在项目中实现人脸识别、车牌检测、实时视频分析等复杂功能OpenCV 都提供了强大而高效的工具集。这个由 C 编写但提供 Python 接口的库已经成为学术界和工业界事实上的标准。对于 Python 开发者来说OpenCV-Python 结合了 OpenCV 的性能优势和 Python 的易用性让计算机视觉项目的开发门槛大大降低。但在实际学习和使用过程中很多人会遇到环境配置复杂、API 理解困难、实际项目集成不顺畅等问题。本文将从最基础的安装配置开始逐步深入到图像处理、视频分析、人脸检测和车牌识别等实战场景帮助读者建立完整的 OpenCV 知识体系。1. OpenCV 环境搭建与基础验证1.1 理解 OpenCV 的版本选择与依赖关系OpenCV 目前主要维护两个大版本分支OpenCV 3.x 和 OpenCV 4.x。对于新项目建议直接使用 OpenCV 4.x因为它包含了更多现代计算机视觉算法和性能优化。但需要注意OpenCV 4.x 移除了一些旧版本的 API如果参考基于 OpenCV 3.x 的教程可能会遇到兼容性问题。在安装 OpenCV for Python 时实际上安装的是opencv-python包这是 OpenCV 官方维护的 Python 绑定。除了基础版本外还有几个变体版本opencv-python包含主要模块的基础版本opencv-contrib-python包含主要模块和 contrib 额外模块opencv-python-headless无 GUI 功能的版本适合服务器环境对于学习和小型项目建议安装opencv-contrib-python因为它包含了更多高级功能如人脸识别、文本检测等。1.2 详细安装步骤与环境验证在开始安装前确保已经安装了 Python 3.6 或更高版本。可以通过以下命令检查 Python 版本python --version # 或 python3 --version推荐使用 pip 进行安装这是最直接的方式pip install opencv-contrib-python如果下载速度较慢可以使用国内镜像源pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后通过简单的 Python 脚本验证安装是否成功import cv2 # 打印 OpenCV 版本 print(OpenCV版本:, cv2.__version__) # 检查基本功能是否正常 import numpy as np # 创建一个简单的黑色图像 img np.zeros((100, 100, 3), dtypenp.uint8) print(图像创建成功形状:, img.shape)如果运行没有报错说明 OpenCV 基本环境配置成功。接下来验证图像读写功能import cv2 import numpy as np import os # 创建一个测试图像 test_img np.random.randint(0, 255, (200, 200, 3), dtypenp.uint8) # 保存图像 cv2.imwrite(test_image.jpg, test_img) # 读取图像 loaded_img cv2.imread(test_image.jpg) # 验证图像是否正确读写 if loaded_img is not None and loaded_img.shape test_img.shape: print(图像读写功能正常) else: print(图像读写功能异常) # 清理测试文件 if os.path.exists(test_image.jpg): os.remove(test_image.jpg)1.3 常见安装问题排查在安装 OpenCV 过程中可能会遇到各种问题。以下是几个典型问题及解决方案问题1ModuleNotFoundError: No module named cv2这种现象通常意味着 OpenCV 没有正确安装或者安装到了不同的 Python 环境。解决方案# 确认当前 Python 环境 which python # 或 which python3 # 使用正确的 pip 安装 pip install opencv-python # 或者如果使用 Python 3 明确指定 pip3 install opencv-python问题2安装过程中出现权限错误在 Linux 或 macOS 上可能会因为权限问题导致安装失败。解决方案# 使用用户安装模式 pip install --user opencv-python # 或使用虚拟环境 python -m venv opencv_env source opencv_env/bin/activate # Linux/macOS # opencv_env\Scripts\activate # Windows pip install opencv-python问题3导入 cv2 时出现 DLL 加载错误Windows这通常是因为缺少 Visual C 运行库。解决方案安装 Microsoft Visual C Redistributable for Visual Studio 2015、2017、2019 和 2022。2. OpenCV 图像处理基础与核心概念2.1 理解图像在 OpenCV 中的表示方式在 OpenCV 中图像被表示为多维 NumPy 数组。理解这种表示方式是使用 OpenCV 的基础。import cv2 import numpy as np # 读取图像 image cv2.imread(path/to/your/image.jpg) # 替换为实际图像路径 if image is not None: print(f图像形状: {image.shape}) print(f图像数据类型: {image.dtype}) print(f图像总像素数: {image.size}) # 对于彩色图像shape 返回 (高度, 宽度, 通道数) # OpenCV 默认使用 BGR 颜色空间而不是常见的 RGB height, width, channels image.shape print(f高度: {height}, 宽度: {width}, 通道数: {channels}) else: print(图像读取失败请检查路径)需要注意的是OpenCV 使用 BGR 颜色顺序而不是常见的 RGB这在与其他库交互时需要特别注意。2.2 基本的图像操作与转换掌握基本的图像操作是进行复杂处理的前提。以下是一些核心操作import cv2 import numpy as np # 创建一个示例图像进行演示 image np.zeros((300, 400, 3), dtypenp.uint8) # 1. 绘制基本图形 # 绘制矩形图像左上角坐标右下角坐标颜色(BGR)线宽 cv2.rectangle(image, (50, 50), (200, 150), (0, 255, 0), 2) # 绘制圆形图像圆心坐标半径颜色线宽-1表示填充 cv2.circle(image, (300, 100), 40, (255, 0, 0), -1) # 绘制文字图像文字内容位置字体大小颜色线宽 cv2.putText(image, OpenCV Demo, (100, 250), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) # 显示图像 cv2.imshow(Basic Operations, image) cv2.waitKey(0) # 等待按键 cv2.destroyAllWindows() # 关闭所有窗口2.3 颜色空间转换与通道操作颜色空间转换是图像处理中的常见操作OpenCV 提供了丰富的颜色空间转换功能。import cv2 import numpy as np # 读取图像 image cv2.imread(path/to/your/image.jpg) if image is not None: # 转换颜色空间 # BGR 转灰度 gray_image cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # BGR 转 HSV色相、饱和度、明度 hsv_image cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR 转 RGB rgb_image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 通道分离与合并 b, g, r cv2.split(image) # 创建一个只显示红色通道的图像 red_channel np.zeros_like(image) red_channel[:, :, 2] r # 在BGR中红色是第2个通道索引2 # 显示各种转换结果 cv2.imshow(Original BGR, image) cv2.imshow(Gray Scale, gray_image) cv2.imshow(Red Channel, red_channel) cv2.waitKey(0) cv2.destroyAllWindows()3. 图像处理进阶滤波、阈值与形态学操作3.1 图像滤波与噪声处理图像滤波是改善图像质量、提取特征的重要手段。OpenCV 提供了多种滤波方法。import cv2 import numpy as np from matplotlib import pyplot as plt # 创建一个带噪声的图像用于演示 image cv2.imread(path/to/your/image.jpg) if image is None: # 如果没有图像创建一个测试图像并添加噪声 image np.ones((300, 400, 3), dtypenp.uint8) * 128 # 添加椒盐噪声 noise np.random.randint(0, 2, image.shape[:2]) image[noise 1] 255 image[noise 0] 0 # 各种滤波方法 # 均值滤波 blurred cv2.blur(image, (5, 5)) # 高斯滤波 gaussian_blur cv2.GaussianBlur(image, (5, 5), 0) # 中值滤波对椒盐噪声特别有效 median_blur cv2.medianBlur(image, 5) # 双边滤波保边去噪 bilateral_blur cv2.bilateralFilter(image, 9, 75, 75) # 使用 matplotlib 显示结果 titles [Original, Blurred, Gaussian Blur, Median Blur, Bilateral Blur] images [image, blurred, gaussian_blur, median_blur, bilateral_blur] plt.figure(figsize(15, 10)) for i in range(5): plt.subplot(2, 3, i1) # 注意 OpenCV 是 BGRmatplotlib 是 RGB if images[i].shape[-1] 3: plt.imshow(cv2.cvtColor(images[i], cv2.COLOR_BGR2RGB)) else: plt.imshow(images[i], cmapgray) plt.title(titles[i]) plt.axis(off) plt.tight_layout() plt.show()3.2 图像阈值处理阈值处理是图像分割的基础用于将图像转换为二值图像。import cv2 import numpy as np from matplotlib import pyplot as plt # 读取图像并转换为灰度 image cv2.imread(path/to/your/image.jpg) if image is not None: gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: # 创建测试图像 gray np.random.randint(0, 255, (200, 200), dtypenp.uint8) # 各种阈值处理方法 # 简单阈值 ret, thresh1 cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 反向阈值 ret, thresh2 cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) # 截断阈值 ret, thresh3 cv2.threshold(gray, 127, 255, cv2.THRESH_TRUNC) # 自适应阈值对光照不均的图像效果好 thresh4 cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) # Otsus 二值化自动确定最佳阈值 ret, thresh5 cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) titles [Original, BINARY, BINARY_INV, TRUNC, ADAPTIVE, OTSU] images [gray, thresh1, thresh2, thresh3, thresh4, thresh5] plt.figure(figsize(15, 8)) for i in range(6): plt.subplot(2, 3, i1) plt.imshow(images[i], gray) plt.title(titles[i]) plt.axis(off) plt.tight_layout() plt.show() print(fOtsus 方法计算的最佳阈值: {ret})3.3 形态学图像处理膨胀与腐蚀形态学操作是基于形状的图像处理技术主要用于二值图像。import cv2 import numpy as np from matplotlib import pyplot as plt # 创建一个简单的二值图像用于演示 image np.zeros((200, 200), dtypenp.uint8) # 在图像中心绘制一个矩形 image[50:150, 50:150] 255 # 添加一些噪声 noise np.random.randint(0, 2, (200, 200)) image[noise 1] 255 - image[noise 1] # 定义结构元素核 kernel np.ones((5, 5), np.uint8) # 腐蚀消除边界点使边界向内部收缩 erosion cv2.erode(image, kernel, iterations1) # 膨胀将边界点向外扩张填补空洞 dilation cv2.dilate(image, kernel, iterations1) # 开运算先腐蚀后膨胀去除小物体 opening cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel) # 闭运算先膨胀后腐蚀填补小洞 closing cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel) # 梯度运算膨胀图减腐蚀图得到物体轮廓 gradient cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel) titles [Original, Erosion, Dilation, Opening, Closing, Gradient] images [image, erosion, dilation, opening, closing, gradient] plt.figure(figsize(15, 8)) for i in range(6): plt.subplot(2, 3, i1) plt.imshow(images[i], gray) plt.title(titles[i]) plt.axis(off) plt.tight_layout() plt.show()4. 视频处理与实时摄像头操作4.1 视频文件读取与处理OpenCV 可以处理各种格式的视频文件基本流程与图像处理类似但需要逐帧处理。import cv2 import numpy as np def process_video(input_path, output_pathNone): 处理视频文件的示例函数 # 创建视频捕获对象 cap cv2.VideoCapture(input_path) # 检查视频是否成功打开 if not cap.isOpened(): print(无法打开视频文件) return # 获取视频属性 fps cap.get(cv2.CAP_PROP_FPS) width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total_frames int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) print(f视频信息: {width}x{height}, FPS: {fps:.2f}, 总帧数: {total_frames}) # 如果需要保存处理后的视频 if output_path: fourcc cv2.VideoWriter_fourcc(*XVID) out cv2.VideoWriter(output_path, fourcc, fps, (width, height)) frame_count 0 while True: # 读取一帧 ret, frame cap.read() if not ret: break frame_count 1 print(f处理第 {frame_count}/{total_frames} 帧, end\r) # 在这里进行帧处理 # 示例转换为灰度并添加文字 processed_frame cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) processed_frame cv2.cvtColor(processed_frame, cv2.COLOR_GRAY2BGR) # 添加帧信息文字 cv2.putText(processed_frame, fFrame: {frame_count}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) # 显示处理后的帧 cv2.imshow(Processed Video, processed_frame) # 保存处理后的帧 if output_path: out.write(processed_frame) # 按 q 键退出 if cv2.waitKey(1) 0xFF ord(q): break # 释放资源 cap.release() if output_path: out.release() cv2.destroyAllWindows() print(f\n视频处理完成共处理 {frame_count} 帧) # 使用示例需要替换为实际视频路径 # process_video(input_video.mp4, output_video.avi)4.2 实时摄像头捕获与处理OpenCV 可以访问摄像头进行实时视频处理这是很多计算机视觉应用的基础。import cv2 import numpy as np import time def real_time_camera_processing(): 实时摄像头处理示例 # 打开默认摄像头0表示第一个摄像头 cap cv2.VideoCapture(0) if not cap.isOpened(): print(无法访问摄像头) return # 设置摄像头分辨率可选 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) print(按 q 退出按 s 保存当前帧) saved_count 0 start_time time.time() frame_count 0 while True: ret, frame cap.read() if not ret: print(无法读取帧) break frame_count 1 # 计算并显示FPS current_time time.time() fps frame_count / (current_time - start_time) # 在帧上添加信息 cv2.putText(frame, fFPS: {fps:.1f}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.putText(frame, Press q to quit, s to save, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) # 显示帧 cv2.imshow(Real-time Camera, frame) # 键盘输入处理 key cv2.waitKey(1) 0xFF if key ord(q): break elif key ord(s): # 保存当前帧 saved_count 1 filename fcaptured_frame_{saved_count}.jpg cv2.imwrite(filename, frame) print(f已保存: {filename}) # 释放资源 cap.release() cv2.destroyAllWindows() print(f程序运行结束共处理 {frame_count} 帧) # 运行实时摄像头处理 # real_time_camera_processing()4.3 视频处理中的性能优化技巧实时视频处理对性能要求较高以下是一些优化建议import cv2 import time def optimized_video_processing(): 优化版的视频处理函数 cap cv2.VideoCapture(0) # 性能优化设置 # 跳过一些帧处理根据实际需求调整 frame_skip 2 frame_counter 0 # 降低分辨率提高处理速度 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) # 使用更快的颜色转换 while True: ret, frame cap.read() if not ret: break frame_counter 1 # 跳帧处理每 frame_skip 帧处理一次 if frame_counter % frame_skip ! 0: continue # 使用更快的处理方式 # 直接处理BGR而不是转换为灰度再转回 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 简单的边缘检测Canny比较耗时可根据需求调整阈值 edges cv2.Canny(gray, 50, 150) # 显示结果 cv2.imshow(Optimized Processing, edges) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows() # 性能对比测试 def performance_comparison(): 对比不同处理方式的性能 cap cv2.VideoCapture(0) # 测试方法1完整处理 start_time time.time() frames_processed 0 while time.time() - start_time 5: # 测试5秒 ret, frame cap.read() if ret: # 复杂处理 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blurred cv2.GaussianBlur(gray, (5, 5), 0) edges cv2.Canny(blurred, 50, 150) frames_processed 1 fps1 frames_processed / 5 print(f复杂处理 FPS: {fps1:.1f}) # 重置摄像头 cap.release() cap cv2.VideoCapture(0) # 测试方法2简化处理 start_time time.time() frames_processed 0 while time.time() - start_time 5: ret, frame cap.read() if ret: # 简单处理 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) frames_processed 1 fps2 frames_processed / 5 print(f简单处理 FPS: {fps2:.1f}) cap.release() print(f性能提升: {(fps2 - fps1) / fps1 * 100:.1f}%)5. 人脸检测实战应用5.1 基于 Haar 级联分类器的人脸检测Haar 级联分类器是 OpenCV 中最常用的人脸检测方法虽然比较传统但效果稳定。import cv2 import numpy as np def face_detection_haar(): 使用 Haar 级联分类器进行人脸检测 # 加载预训练的分类器 # OpenCV 自带了一些训练好的模型 face_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) eye_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_eye.xml) # 初始化摄像头 cap cv2.VideoCapture(0) while True: ret, frame cap.read() if not ret: break # 转换为灰度图像Haar分类器需要灰度图 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 人脸检测 faces face_cascade.detectMultiScale( gray, scaleFactor1.1, # 每次图像尺寸减小的比例 minNeighbors5, # 每个候选矩形应该保留的邻居个数 minSize(30, 30), # 检测对象的最小尺寸 flagscv2.CASCADE_SCALE_IMAGE ) # 在检测到的人脸周围画矩形 for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (xw, yh), (255, 0, 0), 2) # 在人脸区域检测眼睛 roi_gray gray[y:yh, x:xw] roi_color frame[y:yh, x:xw] eyes eye_cascade.detectMultiScale(roi_gray) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (exew, eyeh), (0, 255, 0), 2) # 显示结果 cv2.imshow(Face Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows() # 图像文件中的人脸检测 def detect_faces_in_image(image_path): 在静态图像中检测人脸 # 加载分类器 face_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) # 读取图像 image cv2.imread(image_path) if image is None: print(无法读取图像) return gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 检测人脸 faces face_cascade.detectMultiScale(gray, 1.1, 5) print(f检测到 {len(faces)} 张人脸) # 标记人脸 for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (xw, yh), (0, 255, 0), 2) # 在人脸下方添加文字 cv2.putText(image, Face, (x, yh20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # 显示结果 cv2.imshow(Face Detection Result, image) cv2.waitKey(0) cv2.destroyAllWindows() # 使用示例 # detect_faces_in_image(group_photo.jpg)5.2 人脸检测参数调优与性能优化Haar 级联分类器的参数调优对检测效果影响很大需要根据具体场景进行调整。import cv2 import time def optimized_face_detection(): 优化的人脸检测实现 face_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) cap cv2.VideoCapture(0) # 性能优化降低检测频率 detection_interval 5 # 每5帧检测一次 frame_count 0 last_faces [] # 参数调优记录 scale_factors [1.05, 1.1, 1.2, 1.3] min_neighbors_list [3, 5, 7, 10] current_scale 1.1 current_neighbors 5 while True: ret, frame cap.read() if not ret: break frame_count 1 # 只在检测间隔帧进行人脸检测 if frame_count % detection_interval 0: gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 根据当前参数检测人脸 faces face_cascade.detectMultiScale( gray, scaleFactorcurrent_scale, minNeighborscurrent_neighbors, minSize(30, 30) ) last_faces faces print(f检测到 {len(faces)} 张人脸参数: scale{current_scale}, neighbors{current_neighbors}) # 绘制上一次检测到的人脸 for (x, y, w, h) in last_faces: cv2.rectangle(frame, (x, y), (xw, yh), (0, 255, 0), 2) cv2.putText(frame, fFace, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) # 显示当前参数 cv2.putText(frame, fScale: {current_scale}, Neighbors: {current_neighbors}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) cv2.imshow(Optimized Face Detection, frame) key cv2.waitKey(1) 0xFF if key ord(q): break elif key ord(s): # 切换scale factor current_scale scale_factors[(scale_factors.index(current_scale) 1) % len(scale_factors)] elif key ord(n): # 切换min neighbors current_neighbors min_neighbors_list[ (min_neighbors_list.index(current_neighbors) 1) % len(min_neighbors_list)] cap.release() cv2.destroyAllWindows()5.3 多角度人脸检测与侧脸检测除了正面人脸OpenCV 还支持侧脸和多角度人脸的检测。import cv2 import numpy as np def multi_angle_face_detection(): 多角度人脸检测 # 加载不同角度的分类器 frontal_face cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) profile_face cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_profileface.xml) cap cv2.VideoCapture(0) while True: ret, frame cap.read() if not ret: break gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 检测正面人脸 frontal_faces frontal_face.detectMultiScale(gray, 1.1, 5) for (x, y, w, h) in frontal_faces: cv2.rectangle(frame, (x, y), (xw, yh), (0, 255, 0), 2) cv2.putText(frame, Frontal, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) # 检测侧脸需要镜像图像检测另一侧的侧脸 # 右侧脸 profile_faces profile_face.detectMultiScale(gray, 1.1, 5) for (x, y, w, h) in profile_faces: cv2.rectangle(frame, (x, y), (xw, yh), (255, 0, 0), 2) cv2.putText(frame, Profile Right, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1) # 左侧脸镜像图像检测 flipped_gray cv2.flip(gray, 1) left_profile_faces profile_face.detectMultiScale(flipped_gray, 1.1, 5) for (x, y, w, h) in left_profile_faces: # 转换坐标回原图像 orig_x frame.shape[1] - x - w cv2.rectangle(frame, (orig_x, y), (orig_xw, yh), (0, 0, 255), 2) cv2.putText(frame, Profile Left, (orig_x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) # 显示统计信息 total_faces len(frontal_faces) len(profile_faces) len(left_profile_faces) cv2.putText(frame, fTotal Faces: {total_faces}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) cv2.imshow(Multi-angle Face Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()6. 车牌识别实战项目6.1 车牌检测与定位车牌识别首先需要准确检测和定位车牌区域这是整个系统的基础。import cv2 import numpy as np def license_plate_detection(image_path): 车牌检测与定位 # 读取图像 image cv2.imread(image_path) if image is None: print(无法读取图像) return # 复制原图像用于显示 display_image image.copy() # 转换为灰度图 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 方法1使用边缘检测 # 高斯模糊降噪 blurred cv2.GaussianBlur(gray, (5, 5), 0) # 边缘检测 edges cv2.Canny(blurred, 50, 150) # 形态学操作闭合边缘 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) closed cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # 查找轮廓 contours, _ cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 筛选可能的车牌区域 plate_candidates [] for contour in contours: # 计算轮廓的边界矩形 x, y, w, h cv2.boundingRect(contour) # 根据长宽比和面积筛选 aspect_ratio w / h area w * h # 车牌的典型长宽比约为 3:1 到 4:1 if 2.5 aspect_ratio 5.0 and area 1000: plate_candidates.append((x, y, w, h)) cv2.rectangle(display_image, (x, y), (xw,