
OpenCVOpen Source Computer Vision Library是一个开源的计算机视觉库广泛应用于图像处理、视频分析、机器视觉等领域。作为计算机视觉领域的标准工具库OpenCV提供了丰富的图像处理算法和函数支持多种编程语言其中Python因其简洁易用成为最受欢迎的开发语言之一。本次教程基于2026年最新版OpenCV涵盖从零基础到实战的完整学习路径包括图像处理、视频处理、人脸检测、车牌识别等核心应用场景。无论你是计算机视觉初学者还是有一定经验的开发者都能通过本教程快速掌握OpenCV的核心技能。1. OpenCV核心能力速览能力项说明支持平台Windows、Linux、macOS、Android、iOS编程语言Python、C、Java、JavaScript核心功能图像处理、视频分析、特征检测、目标识别、机器学习硬件要求普通CPU即可运行GPU可加速处理安装方式pip一键安装支持conda环境管理适合场景学术研究、工业检测、安防监控、自动驾驶、医疗影像2. OpenCV环境搭建与安装2.1 Python环境准备首先确保系统已安装Python 3.7及以上版本。推荐使用Anaconda或Miniconda管理Python环境# 创建专用环境 conda create -n opencv_env python3.9 conda activate opencv_env2.2 OpenCV安装通过pip安装OpenCV完整包# 安装OpenCV主包 pip install opencv-python # 安装包含contrib模块的完整版 pip install opencv-contrib-python # 安装额外的依赖库 pip install numpy matplotlib2.3 验证安装创建测试脚本验证安装是否成功import cv2 import numpy as np print(fOpenCV版本: {cv2.__version__}) print(fNumPy版本: {np.__version__}) # 测试基本功能 img np.zeros((100, 100, 3), dtypenp.uint8) cv2.imshow(Test, img) cv2.waitKey(1000) cv2.destroyAllWindows() print(OpenCV安装成功)3. 图像处理基础操作3.1 图像读取与显示import cv2 import matplotlib.pyplot as plt # 读取图像 img cv2.imread(image.jpg) # 转换颜色空间BGR转RGB img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 显示图像 plt.figure(figsize(10, 5)) plt.subplot(121), plt.imshow(img_rgb), plt.title(原始图像) plt.xticks([]), plt.yticks([]) # 灰度图 img_gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) plt.subplot(122), plt.imshow(img_gray, cmapgray), plt.title(灰度图像) plt.xticks([]), plt.yticks([]) plt.show()3.2 图像基本操作# 获取图像信息 height, width, channels img.shape print(f图像尺寸: {width}x{height}, 通道数: {channels}) # 图像裁剪 cropped img[100:300, 200:400] # y:100-300, x:200-400 # 图像缩放 resized cv2.resize(img, (400, 300)) # 宽度400, 高度300 # 图像旋转 rows, cols img.shape[:2] M cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1) # 旋转45度 rotated cv2.warpAffine(img, M, (cols, rows))4. 图像几何变换实战4.1 图像缩放实现import cv2 import numpy as np def image_resize_demo(): # 读取图像 src cv2.imread(1.jpg) if src is None: print(图像读取失败请检查文件路径) return # 获取原图尺寸 height, width src.shape[:2] print(f原图尺寸: 宽度{width}像素, 高度{height}像素) # 放大1.2倍 res1 cv2.resize(src, (int(1.2*width), int(1.2*height)), interpolationcv2.INTER_CUBIC) # 缩小到0.6倍 res2 cv2.resize(src, (int(0.6*width), int(0.6*height)), interpolationcv2.INTER_CUBIC) # 显示结果 cv2.imshow(Original, src) cv2.imshow(Enlarged 1.2x, res1) cv2.imshow(Reduced 0.6x, res2) print(f放大后尺寸: {res1.shape[1]}x{res1.shape[0]}) print(f缩小后尺寸: {res2.shape[1]}x{res2.shape[0]}) cv2.waitKey(0) cv2.destroyAllWindows() # 执行缩放演示 image_resize_demo()4.2 仿射变换平移与旋转def affine_transformation_demo(): # 平移变换 img cv2.imread(1.jpg) rows, cols, ch img.shape # 创建平移矩阵 [[1, 0, tx], [0, 1, ty]] M_translation np.float32([[1, 0, 300], [0, 1, 50]]) dst_translation cv2.warpAffine(img, M_translation, (cols, rows)) # 旋转变换 M_rotation cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90, 1) dst_rotation cv2.warpAffine(img, M_rotation, (cols, rows)) # 显示结果 cv2.imshow(Original, img) cv2.imshow(Translation, dst_translation) cv2.imshow(Rotation 90°, dst_rotation) cv2.waitKey(0) cv2.destroyAllWindows() affine_transformation_demo()4.3 透视变换实战def perspective_transform_demo(): img cv2.imread(1.jpg) rows, cols img.shape[:2] # 定义原始四边形顶点和目标矩形顶点 pts1 np.float32([[150, 50], [400, 50], [60, 450], [310, 450]]) pts2 np.float32([[50, 50], [rows-50, 50], [50, cols-50], [rows-50, cols-50]]) # 计算透视变换矩阵 M cv2.getPerspectiveTransform(pts1, pts2) dst cv2.warpPerspective(img, M, (cols, rows)) # 显示结果 cv2.imshow(Original, img) cv2.imshow(Perspective Transform, dst) cv2.waitKey(0) cv2.destroyAllWindows() perspective_transform_demo()5. 图像滤波与噪声处理5.1 图像噪声类型与处理图像在采集和传输过程中会受到各种噪声干扰常见的噪声类型包括椒盐噪声随机出现的黑白点状噪声高斯噪声符合正态分布的随机噪声5.2 滤波算法实现def image_filtering_demo(): # 读取带噪声的图像 img cv2.imread(noise.jpg) if img is None: # 生成示例噪声图像 img cv2.imread(1.jpg) # 添加椒盐噪声 noise_img img.copy() prob 0.05 thres 1 - prob for i in range(img.shape[0]): for j in range(img.shape[1]): rdn np.random.random() if rdn prob: noise_img[i][j] 0 elif rdn thres: noise_img[i][j] 255 img noise_img # 均值滤波 blur_mean cv2.blur(img, (5, 5)) # 高斯滤波 blur_gauss cv2.GaussianBlur(img, (5, 5), 1) # 中值滤波 blur_median cv2.medianBlur(img, 5) # 显示结果 plt.figure(figsize(12, 8)) plt.subplot(221), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(Noisy Image), plt.xticks([]), plt.yticks([]) plt.subplot(222), plt.imshow(cv2.cvtColor(blur_mean, cv2.COLOR_BGR2RGB)) plt.title(Mean Filtering), plt.xticks([]), plt.yticks([]) plt.subplot(223), plt.imshow(cv2.cvtColor(blur_gauss, cv2.COLOR_BGR2RGB)) plt.title(Gaussian Filtering), plt.xticks([]), plt.yticks([]) plt.subplot(224), plt.imshow(cv2.cvtColor(blur_median, cv2.COLOR_BGR2RGB)) plt.title(Median Filtering), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() image_filtering_demo()6. 边缘检测技术深度解析6.1 边缘检测原理边缘检测是计算机视觉中的基础任务目的是识别图像中亮度明显变化的点。OpenCV提供了多种边缘检测算法其中最著名的是Canny边缘检测。6.2 Canny边缘检测实现def edge_detection_demo(): # 读取图像 img cv2.imread(luna.jpg) if img is None: img cv2.imread(1.jpg) # 转换为灰度图 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Canny边缘检测 lowThreshold 1 max_lowThreshold 80 edges cv2.Canny(gray, lowThreshold, max_lowThreshold) # 显示结果 plt.figure(figsize(10, 5)) plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(Original Image), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(edges, cmapgray) plt.title(Canny Edge Detection), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() edge_detection_demo()6.3 边缘检测算法对比def edge_detection_comparison(): img cv2.imread(1.jpg) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 不同的边缘检测方法 edges_sobelx cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize5) edges_sobely cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize5) edges_laplacian cv2.Laplacian(gray, cv2.CV_64F) edges_canny cv2.Canny(gray, 100, 200) # 显示结果 plt.figure(figsize(12, 8)) plt.subplot(231), plt.imshow(gray, cmapgray) plt.title(Original Gray), plt.xticks([]), plt.yticks([]) plt.subplot(232), plt.imshow(edges_sobelx, cmapgray) plt.title(Sobel X), plt.xticks([]), plt.yticks([]) plt.subplot(233), plt.imshow(edges_sobely, cmapgray) plt.title(Sobel Y), plt.xticks([]), plt.yticks([]) plt.subplot(234), plt.imshow(edges_laplacian, cmapgray) plt.title(Laplacian), plt.xticks([]), plt.yticks([]) plt.subplot(235), plt.imshow(edges_canny, cmapgray) plt.title(Canny), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() edge_detection_comparison()7. 形态学图像处理7.1 形态学基本操作形态学处理主要用于提取图像中的形状特征包括腐蚀、膨胀、开运算、闭运算等基本操作。def morphology_operations_demo(): # 读取图像 img_org cv2.imread(example_org.jpg) if img_org is None: # 创建示例图像 img_org np.zeros((200, 200), dtypenp.uint8) cv2.rectangle(img_org, (50, 50), (150, 150), 255, -1) cv2.circle(img_org, (100, 100), 30, 0, -1) # 创建核结构 kernel np.ones((10, 10), np.uint8) # 形态学操作 erosion cv2.erode(img_org, kernel) # 腐蚀 dilation cv2.dilate(img_org, kernel) # 膨胀 opening cv2.morphologyEx(img_org, cv2.MORPH_OPEN, kernel) # 开运算 closing cv2.morphologyEx(img_org, cv2.MORPH_CLOSE, kernel) # 闭运算 gradient cv2.morphologyEx(img_org, cv2.MORPH_GRADIENT, kernel) # 梯度 # 显示结果 images [img_org, erosion, dilation, opening, closing, gradient] titles [Original, Erosion, Dilation, Opening, Closing, Gradient] plt.figure(figsize(15, 8)) for i in range(6): plt.subplot(2, 3, i1) plt.imshow(images[i], cmapgray) plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() morphology_operations_demo()8. 图像阈值处理技术8.1 全局阈值处理def threshold_demo(): img cv2.imread(test.jpg) if img is None: img cv2.imread(1.jpg) img_gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 不同的全局阈值处理方法 ret, thresh1 cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) ret, thresh2 cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) ret, thresh3 cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC) ret, thresh4 cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO) ret, thresh5 cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV) titles [Original, BINARY, BINARY_INV, TRUNC, TOZERO, TOZERO_INV] images [img_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], cmapgray) plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() threshold_demo()8.2 自适应阈值处理def adaptive_threshold_demo(): img cv2.imread(test.jpg) if img is None: img cv2.imread(1.jpg) img_gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 全局阈值 ret, th1 cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) # 自适应阈值 th2 cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th3 cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) titles [Original, Global Thresholding, Adaptive Mean, Adaptive Gaussian] images [img_gray, th1, th2, th3] plt.figure(figsize(12, 8)) for i in range(4): plt.subplot(2, 2, i1) plt.imshow(images[i], cmapgray) plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() adaptive_threshold_demo()8.3 Otsu阈值处理def otsu_threshold_demo(): img cv2.imread(test.jpg) if img is None: img cv2.imread(1.jpg) img_gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 全局阈值 ret1, th1 cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) # Otsu阈值处理 ret2, th2 cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 高斯滤波后Otsu blur cv2.GaussianBlur(img_gray, (5, 5), 0) ret3, th3 cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) images [img_gray, 0, th1, img_gray, 0, th2, blur, 0, th3] titles [Original Noisy Image,Histogram,Global Thresholding (v127), Original Noisy Image,Histogram,Otsus Thresholding, Gaussian filtered Image,Histogram,Otsus Thresholding] plt.figure(figsize(16, 12)) for i in range(3): plt.subplot(3, 3, i*31) plt.imshow(images[i*3], cmapgray) plt.title(titles[i*3]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i*32) plt.hist(images[i*3].ravel(), 256) plt.title(titles[i*31]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i*33) plt.imshow(images[i*32], cmapgray) plt.title(titles[i*32]), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() otsu_threshold_demo()9. 轮廓检测与特征提取9.1 轮廓查找与绘制def contour_detection_demo(): # 创建测试图像 img np.zeros((200, 200), dtypenp.uint8) cv2.rectangle(img, (20, 20), (80, 80), 255, -1) cv2.circle(img, (150, 150), 30, 255, -1) cv2.rectangle(img, (100, 50), (180, 100), 255, -1) # 查找轮廓 contours, hierarchy cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 绘制轮廓 img_color cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2.drawContours(img_color, contours, -1, (0, 255, 0), 2) # 显示结果 plt.figure(figsize(10, 5)) plt.subplot(121), plt.imshow(img, cmapgray) plt.title(Binary Image), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)) plt.title(Detected Contours), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() print(f检测到 {len(contours)} 个轮廓) contour_detection_demo()9.2 轮廓特征分析def contour_features_demo(): # 创建测试图像 img np.zeros((200, 200), dtypenp.uint8) cv2.rectangle(img, (30, 30), (100, 100), 255, -1) cv2.circle(img, (150, 150), 40, 255, -1) contours, _ cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) img_color cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) for i, contour in enumerate(contours): # 计算轮廓面积 area cv2.contourArea(contour) # 计算轮廓周长 perimeter cv2.arcLength(contour, True) # 轮廓近似 epsilon 0.02 * perimeter approx cv2.approxPolyDP(contour, epsilon, True) # 计算边界矩形 x, y, w, h cv2.boundingRect(contour) cv2.rectangle(img_color, (x, y), (xw, yh), (0, 255, 0), 2) # 计算最小外接圆 (x, y), radius cv2.minEnclosingCircle(contour) center (int(x), int(y)) radius int(radius) cv2.circle(img_color, center, radius, (255, 0, 0), 2) print(f轮廓 {i1}: 面积{area:.2f}, 周长{perimeter:.2f}, 顶点数{len(approx)}) plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)) plt.title(Contour Features), plt.xticks([]), plt.yticks([]) plt.show() contour_features_demo()10. 实战项目人脸检测与车牌识别10.1 人脸检测实现def face_detection_demo(): # 加载人脸检测器 face_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) # 读取图像 img cv2.imread(group_photo.jpg) if img is None: print(请准备测试图像或使用摄像头实时检测) return gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测人脸 faces face_cascade.detectMultiScale(gray, 1.1, 4) # 绘制检测框 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (xw, yh), (255, 0, 0), 2) # 显示结果 plt.figure(figsize(10, 8)) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(fDetected {len(faces)} Faces) plt.xticks([]), plt.yticks([]) plt.show() face_detection_demo()10.2 实时人脸检测def realtime_face_detection(): face_cascade cv2.CascadeClassifier(cv2.data.haarcascades haarcascade_frontalface_default.xml) # 打开摄像头 cap cv2.VideoCapture(0) if not cap.isOpened(): print(无法打开摄像头) return print(按 q 键退出实时检测) while True: ret, frame cap.read() if not ret: break gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces face_cascade.detectMultiScale(gray, 1.1, 4) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (xw, yh), (255, 0, 0), 2) cv2.putText(frame, Face, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2) cv2.imshow(Real-time Face Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows() # 取消注释以运行实时检测 # realtime_face_detection()10.3 车牌识别系统def license_plate_detection(): # 读取图像 img cv2.imread(car_plate.jpg) if img is None: print(请准备包含车牌的测试图像) return # 转换为灰度图 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 图像预处理 blurred cv2.GaussianBlur(gray, (5, 5), 0) edged cv2.Canny(blurred, 50, 200) # 查找轮廓 contours, _ cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours sorted(contours, keycv2.contourArea, reverseTrue)[:10] plate_contour None for contour in contours: # 轮廓近似 perimeter cv2.arcLength(contour, True) approx cv2.approxPolyDP(contour, 0.02 * perimeter, True) # 如果是四边形认为是车牌 if len(approx) 4: plate_contour approx break if plate_contour is not None: # 绘制车牌区域 cv2.drawContours(img, [plate_contour], -1, (0, 255, 0), 3) # 提取车牌区域 x, y, w, h cv2.boundingRect(plate_contour) plate_region img[y:yh, x:xw] # 显示结果 plt.figure(figsize(12, 6)) plt.subplot(131), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(Original with Plate Detection), plt.xticks([]), plt.yticks([]) plt.subplot(132), plt.imshow(edged, cmapgray) plt.title(Edge Detection), plt.xticks([]), plt.yticks([]) plt.subplot(133), plt.imshow(cv2.cvtColor(plate_region, cv2.COLOR_BGR2RGB)) plt.title(License Plate Region), plt.xticks([]), plt.yticks([]) plt.tight_layout() plt.show() else: print(未检测到车牌) license_plate_detection()11. 视频处理实战11.1 视频读取与处理def video_processing_demo(): # 创建视频捕获对象 cap cv2.VideoCapture(sample_video.mp4) 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}, 总帧数: {total_frames}) # 创建视频写入对象 fourcc cv2.VideoWriter_fourcc(*XVID) out cv2.VideoWriter(output_video.avi, fourcc, fps, (width, height)) frame_count 0 while True: ret, frame cap.read() if not ret: break # 图像处理边缘检测 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) edges cv2.Canny(gray, 100, 200) # 将边缘检测结果转换为BGR格式 edges_bgr cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR) # 合并原图和边缘检测结果 processed_frame cv2.addWeighted(frame, 0.7, edges_bgr, 0.3, 0) # 写入处理后的帧 out.write(processed_frame) frame_count 1 if frame_count % 30 0: # 每30帧显示一次进度 print(f处理进度: {frame_count}/{total_frames} ({frame_count/total_frames*100:.1f}%)) cap.release() out.release() print(视频处理完成) # 准备视频文件后取消注释运行 # video_processing_demo()11.2 实时视频滤镜def realtime_video_filter(): cap cv2.VideoCapture(0) if not cap.isOpened(): print(无法打开摄像头) return print(实时视频滤镜 - 按 q 退出, c 切换滤镜) filter_mode 0 filter_names [原图, 灰度, 边缘检测, 模糊, 反转颜色] while True: ret, frame cap.read() if not ret: break if filter_mode 0: # 原图 processed frame elif filter_mode 1: # 灰度 processed cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) processed cv2.cvtColor(processed, cv2.COLOR_GRAY2BGR) elif filter_mode 2: # 边缘检测 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) edges cv2.Canny(gray, 100, 200) processed cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR) elif filter_mode 3: # 模糊 processed cv2.GaussianBlur(frame, (15, 15), 0) elif filter_mode 4: # 反转颜色 processed cv2.bitwise_not(frame) # 显示滤镜名称 cv2.putText(processed, fFilter: {filter_names[filter_mode]}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow(Real-time Video Filter, processed) key cv2.waitKey(1) 0xFF if key ord(q): break elif key ord(c): filter_mode (filter_mode 1) % len(filter_names) cap.release() cv2.destroyAllWindows() # 取消注释以运行实时视频滤镜 # realtime_video_filter()12. 性能优化与最佳实践12.1 OpenCV性能优化技巧import time def performance_optimization_demo(): img cv2.imread(1.jpg) if img is None: print(请准备测试图像) return # 测试不同操作的性能 operations { 高斯模糊: lambda img: cv2.GaussianBlur(img, (15, 15), 0), 边缘检测: lambda img: cv2.Canny(img, 100, 200), 形态学操作: lambda img: cv2.morphologyEx(img, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8)), 颜色转换: lambda img: cv2.cvtColor(img, cv2.COLOR_BGR2HSV), 缩放操作: lambda img: cv2.resize(img, (img.shape[1]//2, img.shape[0]//2)) } print(性能测试结果:) print(- * 50) for name, operation in operations.items(): start_time time.time() # 运行10次取平均值 for _ in range(10): result operation(img) end_time time.time() avg_time (end_time - start_time) * 1000 / 10 # 转换为毫秒 print(f{name:15} 平均耗时: {avg_time:.2f} 毫秒