资讯动态

OpenCV图像处理7大实战项目:从基础操作到目标检测完整指南

发布时间:2026/9/8 7:46:34 来源:尧图企业网站定制
在图像处理与计算机视觉领域项目实战是巩固理论知识、提升工程能力的关键环节。本文将以图像7.项目1-7为核心主题系统讲解七个完整的图像处理实战项目涵盖从基础操作到高级应用的完整技术栈。每个项目都包含详细的需求分析、代码实现、运行演示和常见问题解决方案适合有一定Python和OpenCV基础的开发者深入学习。通过本文的学习你将掌握图像处理的核心技术链包括图像增强、特征提取、目标检测、图像分割等关键技能能够独立完成从简单图像处理到复杂视觉应用的开发工作。1. 图像处理基础与环境搭建1.1 环境要求与工具准备图像处理项目通常需要以下环境配置Python 3.7及以上版本OpenCV 4.5及以上版本NumPy科学计算库Matplotlib可视化库Jupyter Notebook可选用于交互式开发安装命令如下pip install opencv-python numpy matplotlib jupyter1.2 基础图像操作在开始具体项目前需要掌握基本的图像读写和显示操作import cv2 import numpy as np import matplotlib.pyplot as plt # 读取图像 def read_image(image_path): 读取图像文件并返回numpy数组 Args: image_path: 图像文件路径 Returns: image: 图像数组 image cv2.imread(image_path) if image is None: raise ValueError(f无法读取图像: {image_path}) return image # 显示图像 def display_image(image, titleImage): 使用Matplotlib显示图像 Args: image: 输入图像 title: 图像标题 # 转换BGR到RGB格式 if len(image.shape) 3: image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) else: image_rgb image plt.figure(figsize(10, 8)) plt.imshow(image_rgb, cmapgray if len(image.shape) 2 else None) plt.title(title) plt.axis(off) plt.show() # 示例使用 if __name__ __main__: # 读取测试图像 img read_image(test_image.jpg) print(f图像形状: {img.shape}) display_image(img, 原始图像)2. 项目1图像灰度化与二值化处理2.1 项目需求分析灰度化和二值化是图像处理的基础操作广泛应用于图像预处理、文档扫描、OCR识别等场景。本项目需要实现将彩色图像转换为灰度图像基于阈值将灰度图像二值化支持多种二值化算法全局阈值、自适应阈值2.2 核心代码实现class ImageConverter: 图像转换器类 def __init__(self): self.available_methods [global, adaptive, otsu] def to_grayscale(self, image): 转换为灰度图像 if len(image.shape) 3: return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) return image def global_threshold(self, gray_image, threshold127): 全局阈值二值化 _, binary cv2.threshold(gray_image, threshold, 255, cv2.THRESH_BINARY) return binary def adaptive_threshold(self, gray_image, block_size11, c2): 自适应阈值二值化 # 确保block_size为奇数 if block_size % 2 0: block_size 1 binary cv2.adaptiveThreshold( gray_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, block_size, c ) return binary def otsu_threshold(self, gray_image): Otsu阈值二值化 _, binary cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) return binary def convert_image(self, image, methodglobal, **kwargs): 完整的图像转换流程 # 转换为灰度图 gray self.to_grayscale(image) # 根据方法选择二值化算法 if method global: threshold kwargs.get(threshold, 127) binary self.global_threshold(gray, threshold) elif method adaptive: block_size kwargs.get(block_size, 11) c kwargs.get(c, 2) binary self.adaptive_threshold(gray, block_size, c) elif method otsu: binary self.otsu_threshold(gray) else: raise ValueError(f不支持的方法: {method}) return gray, binary # 使用示例 converter ImageConverter() image read_image(sample.jpg) # 不同方法的二值化结果 methods [global, adaptive, otsu] results {} for method in methods: gray, binary converter.convert_image(image, methodmethod) results[method] (gray, binary) display_image(binary, f{method}二值化结果)2.3 效果分析与参数调优不同二值化方法适用于不同场景全局阈值适用于光照均匀、对比度明显的图像自适应阈值适用于光照不均的图像如文档扫描Otsu阈值自动计算最佳阈值适合大多数场景3. 项目2图像边缘检测与轮廓提取3.1 技术原理介绍边缘检测是计算机视觉中的重要技术用于识别图像中的物体边界。常用的边缘检测算法包括Sobel算子基于一阶导数Canny算法多阶段边缘检测效果最佳Laplacian算子基于二阶导数3.2 边缘检测实现class EdgeDetector: 边缘检测器 def __init__(self): self.kernel_sizes [3, 5, 7] def sobel_edge(self, image, ksize3): Sobel边缘检测 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image # 计算x和y方向的梯度 sobelx cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksizeksize) sobely cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksizeksize) # 计算梯度幅值 magnitude np.sqrt(sobelx**2 sobely**2) magnitude np.uint8(255 * magnitude / np.max(magnitude)) return magnitude, sobelx, sobely def canny_edge(self, image, low_threshold50, high_threshold150): Canny边缘检测 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image edges cv2.Canny(gray, low_threshold, high_threshold) return edges def laplacian_edge(self, image, ksize3): Laplacian边缘检测 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image laplacian cv2.Laplacian(gray, cv2.CV_64F, ksizeksize) laplacian np.uint8(np.absolute(laplacian)) return laplacian # 轮廓提取功能 class ContourExtractor: 轮廓提取器 def find_contours(self, binary_image, modecv2.RETR_EXTERNAL, methodcv2.CHAIN_APPROX_SIMPLE): 查找轮廓 contours, hierarchy cv2.findContours(binary_image, mode, method) return contours, hierarchy def draw_contours(self, image, contours, color(0, 255, 0), thickness2): 绘制轮廓 result image.copy() cv2.drawContours(result, contours, -1, color, thickness) return result def filter_contours_by_area(self, contours, min_area100, max_area10000): 根据面积过滤轮廓 filtered_contours [] for contour in contours: area cv2.contourArea(contour) if min_area area max_area: filtered_contours.append(contour) return filtered_contours # 完整示例 def edge_detection_demo(image_path): 边缘检测与轮廓提取完整演示 image read_image(image_path) # 边缘检测 detector EdgeDetector() canny_edges detector.canny_edge(image) # 轮廓提取 extractor ContourExtractor() contours, _ extractor.find_contours(canny_edges) filtered_contours extractor.filter_contours_by_area(contours) # 绘制结果 contour_image extractor.draw_contours(image, filtered_contours) # 显示结果 plt.figure(figsize(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title(原始图像) plt.axis(off) plt.subplot(1, 3, 2) plt.imshow(canny_edges, cmapgray) plt.title(Canny边缘) plt.axis(off) plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(contour_image, cv2.COLOR_BGR2RGB)) plt.title(提取的轮廓) plt.axis(off) plt.tight_layout() plt.show() print(f找到轮廓数量: {len(contours)}) print(f过滤后轮廓数量: {len(filtered_contours)}) # 运行演示 edge_detection_demo(sample_object.jpg)4. 项目3图像滤波与噪声处理4.1 噪声类型与滤波算法图像噪声会影响后续处理效果常见的噪声类型包括高斯噪声符合正态分布的随机噪声椒盐噪声随机出现的黑白像素点泊松噪声光子计数噪声对应的滤波算法均值滤波简单快速但会模糊边缘中值滤波有效去除椒盐噪声保护边缘高斯滤波平滑图像保持边缘信息4.2 噪声添加与滤波实现class NoiseGenerator: 噪声生成器 def add_gaussian_noise(self, image, mean0, sigma25): 添加高斯噪声 noisy_image image.astype(np.float64) noise np.random.normal(mean, sigma, image.shape) noisy_image noise noisy_image np.clip(noisy_image, 0, 255).astype(np.uint8) return noisy_image def add_salt_pepper_noise(self, image, salt_prob0.01, pepper_prob0.01): 添加椒盐噪声 noisy_image image.copy() # 盐噪声白点 salt_mask np.random.random(image.shape[:2]) salt_prob noisy_image[salt_mask] 255 # 椒噪声黑点 pepper_mask np.random.random(image.shape[:2]) pepper_prob noisy_image[pepper_mask] 0 return noisy_image class ImageFilter: 图像滤波器 def mean_filter(self, image, kernel_size3): 均值滤波 return cv2.blur(image, (kernel_size, kernel_size)) def median_filter(self, image, kernel_size3): 中值滤波 return cv2.medianBlur(image, kernel_size) def gaussian_filter(self, image, kernel_size3, sigma0): 高斯滤波 return cv2.GaussianBlur(image, (kernel_size, kernel_size), sigma) def bilateral_filter(self, image, d9, sigma_color75, sigma_space75): 双边滤波保边滤波 return cv2.bilateralFilter(image, d, sigma_color, sigma_space) def noise_filtering_comparison(image_path): 噪声与滤波效果对比 original read_image(image_path) # 生成噪声图像 noise_gen NoiseGenerator() gaussian_noisy noise_gen.add_gaussian_noise(original) salt_pepper_noisy noise_gen.add_salt_pepper_noise(original) # 应用不同滤波 filter_obj ImageFilter() # 对高斯噪声的处理 gaussian_denoised filter_obj.gaussian_filter(gaussian_noisy) bilateral_denoised filter_obj.bilateral_filter(gaussian_noisy) # 对椒盐噪声的处理 median_denoised filter_obj.median_filter(salt_pepper_noisy) mean_denoised filter_obj.mean_filter(salt_pepper_noisy) # 显示结果 images [ original, gaussian_noisy, gaussian_denoised, bilateral_denoised, salt_pepper_noisy, median_denoised, mean_denoised ] titles [ 原始图像, 高斯噪声, 高斯滤波, 双边滤波, 椒盐噪声, 中值滤波, 均值滤波 ] plt.figure(figsize(15, 10)) for i in range(7): plt.subplot(3, 3, i1) if len(images[i].shape) 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() # 运行示例 noise_filtering_comparison(sample_image.jpg)5. 项目4图像几何变换与校正5.1 几何变换基础几何变换包括平移、旋转、缩放、仿射变换和透视变换广泛应用于图像校正、图像配准等场景。5.2 变换矩阵与实现class GeometricTransformer: 几何变换器 def translate(self, image, tx, ty): 平移变换 rows, cols image.shape[:2] M np.float32([[1, 0, tx], [0, 1, ty]]) return cv2.warpAffine(image, M, (cols, rows)) def rotate(self, image, angle, centerNone, scale1.0): 旋转变换 rows, cols image.shape[:2] if center is None: center (cols//2, rows//2) M cv2.getRotationMatrix2D(center, angle, scale) return cv2.warpAffine(image, M, (cols, rows)) def scale(self, image, fx, fy, interpolationcv2.INTER_LINEAR): 缩放变换 return cv2.resize(image, None, fxfx, fyfy, interpolationinterpolation) def affine_transform(self, image, src_points, dst_points): 仿射变换 rows, cols image.shape[:2] M cv2.getAffineTransform(np.float32(src_points), np.float32(dst_points)) return cv2.warpAffine(image, M, (cols, rows)) def perspective_transform(self, image, src_points, dst_points): 透视变换用于图像校正 rows, cols image.shape[:2] M cv2.getPerspectiveTransform(np.float32(src_points), np.float32(dst_points)) return cv2.warpPerspective(image, M, (cols, rows)) class DocumentCorrector: 文档图像校正器 def __init__(self): self.detector EdgeDetector() self.extractor ContourExtractor() def correct_document(self, image): 文档图像自动校正 # 边缘检测 edges self.detector.canny_edge(image, 50, 150) # 查找轮廓 contours, _ self.extractor.find_contours(edges) # 找到最大的四边形轮廓假设为文档边界 document_contour None max_area 0 for contour in contours: # 近似轮廓 epsilon 0.02 * cv2.arcLength(contour, True) approx cv2.approxPolyDP(contour, epsilon, True) # 如果是四边形且面积最大 if len(approx) 4: area cv2.contourArea(contour) if area max_area: max_area area document_contour approx if document_contour is None: print(未找到文档边界) return image # 重新排序角点左上、右上、右下、左下 points document_contour.reshape(4, 2) rect np.zeros((4, 2), dtypenp.float32) # 计算中心点 center np.mean(points, axis0) # 区分四个角点 for point in points: if point[0] center[0] and point[1] center[1]: rect[0] point # 左上 elif point[0] center[0] and point[1] center[1]: rect[1] point # 右上 elif point[0] center[0] and point[1] center[1]: rect[2] point # 右下 else: rect[3] point # 左下 # 目标点A4纸比例 width max( np.linalg.norm(rect[0] - rect[1]), np.linalg.norm(rect[2] - rect[3]) ) height max( np.linalg.norm(rect[0] - rect[3]), np.linalg.norm(rect[1] - rect[2]) ) dst_points np.float32([ [0, 0], [width, 0], [width, height], [0, height] ]) # 透视变换 transformer GeometricTransformer() corrected transformer.perspective_transform(image, rect, dst_points) return corrected, rect # 使用示例 def document_correction_demo(image_path): 文档校正演示 image read_image(image_path) corrector DocumentCorrector() corrected_image, corners corrector.correct_document(image) # 绘制角点 corner_image image.copy() for corner in corners: cv2.circle(corner_image, tuple(corner.astype(int)), 10, (0, 255, 0), -1) # 显示结果 plt.figure(figsize(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title(原始文档图像) plt.axis(off) plt.subplot(1, 3, 2) plt.imshow(cv2.cvtColor(corner_image, cv2.COLOR_BGR2RGB)) plt.title(检测到的角点) plt.axis(off) plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(corrected_image, cv2.COLOR_BGR2RGB)) plt.title(校正后的图像) plt.axis(off) plt.tight_layout() plt.show() document_correction_demo(document_image.jpg)6. 项目5图像特征提取与匹配6.1 特征检测算法特征提取是计算机视觉的核心技术常用的特征检测算法包括SIFT尺度不变特征变换SURF加速稳健特征ORBOriented FAST and Rotated BRIEF6.2 特征提取与匹配实现class FeatureExtractor: 特征提取器 def __init__(self, methodORB): self.method method if method SIFT: self.detector cv2.SIFT_create() elif method ORB: self.detector cv2.ORB_create() else: raise ValueError(不支持的特征检测方法) def extract_features(self, image): 提取特征点和描述符 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image keypoints, descriptors self.detector.detectAndCompute(gray, None) return keypoints, descriptors def match_features(self, descriptors1, descriptors2, methodBF, ratio0.75): 特征匹配 if method BF: # 暴力匹配 if self.method SIFT: matcher cv2.BFMatcher(cv2.NORM_L2) else: matcher cv2.BFMatcher(cv2.NORM_HAMMING) matches matcher.knnMatch(descriptors1, descriptors2, k2) # 应用比率测试 good_matches [] for m, n in matches: if m.distance ratio * n.distance: good_matches.append(m) return good_matches elif method FLANN: # FLANN匹配器 if self.method SIFT: index_params dict(algorithm1, trees5) else: index_params dict(algorithm6, table_number6, key_size12, multi_probe_level1) search_params dict(checks50) flann cv2.FlannBasedMatcher(index_params, search_params) matches flann.knnMatch(descriptors1, descriptors2, k2) good_matches [] for m, n in matches: if m.distance ratio * n.distance: good_matches.append(m) return good_matches def feature_matching_demo(image1_path, image2_path): 特征匹配演示 img1 read_image(image1_path) img2 read_image(image2_path) # 提取特征 extractor FeatureExtractor(ORB) kp1, desc1 extractor.extract_features(img1) kp2, desc2 extractor.extract_features(img2) # 特征匹配 matches extractor.match_features(desc1, desc2) # 绘制匹配结果 match_img cv2.drawMatches( img1, kp1, img2, kp2, matches[:50], None, flagscv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS ) # 显示结果 plt.figure(figsize(15, 10)) plt.imshow(cv2.cvtColor(match_img, cv2.COLOR_BGR2RGB)) plt.title(f特征匹配结果 (匹配点数量: {len(matches)})) plt.axis(off) plt.show() print(f图像1特征点数量: {len(kp1)}) print(f图像2特征点数量: {len(kp2)}) print(f匹配点数量: {len(matches)}) # 运行示例 feature_matching_demo(image1.jpg, image2.jpg)7. 项目6图像分割技术7.1 分割算法概述图像分割是将图像划分为有意义的区域的过程主要方法包括阈值分割基于像素强度边缘检测分割基于边界信息区域生长基于相似性分水岭算法基于形态学7.2 多种分割算法实现class ImageSegmenter: 图像分割器 def threshold_segmentation(self, image, threshold_methodotsu): 阈值分割 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image if threshold_method otsu: _, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) else: _, binary cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) return binary def watershed_segmentation(self, image): 分水岭分割 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) 3 else image # 二值化 _, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU) # 形态学操作去除噪声 kernel np.ones((3, 3), np.uint8) opening cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations2) # 确定背景区域 sure_bg cv2.dilate(opening, kernel, iterations3) # 确定前景区域 dist_transform cv2.distanceTransform(opening, cv2.DIST_L2, 5) _, sure_fg cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0) sure_fg np.uint8(sure_fg) # 找到未知区域 unknown cv2.subtract(sure_bg, sure_fg) # 标记连通组件 _, markers cv2.connectedComponents(sure_fg) markers markers 1 markers[unknown 255] 0 # 应用分水岭算法 markers cv2.watershed(image, markers) image[markers -1] [255, 0, 0] # 标记边界 return image, markers def kmeans_segmentation(self, image, k3): K-means聚类分割 # 转换图像格式 data image.reshape((-1, 3)) data np.float32(data) # 定义K-means参数 criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0) _, labels, centers cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) # 转换回uint8 centers np.uint8(centers) segmented_data centers[labels.flatten()] segmented_image segmented_data.reshape(image.shape) return segmented_image def segmentation_comparison(image_path): 不同分割方法对比 image read_image(image_path) segmenter ImageSegmenter() # 应用不同分割方法 threshold_result segmenter.threshold_segmentation(image) kmeans_result segmenter.kmeans_segmentation(image, k3) watershed_result, markers segmenter.watershed_segmentation(image) # 显示结果 plt.figure(figsize(15, 10)) plt.subplot(2, 2, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title(原始图像) plt.axis(off) plt.subplot(2, 2, 2) plt.imshow(threshold_result, cmapgray) plt.title(阈值分割) plt.axis(off) plt.subplot(2, 2, 3) plt.imshow(cv2.cvtColor(kmeans_result, cv2.COLOR_BGR2RGB)) plt.title(K-means分割) plt.axis(off) plt.subplot(2, 2, 4) plt.imshow(cv2.cvtColor(watershed_result, cv2.COLOR_BGR2RGB)) plt.title(分水岭分割) plt.axis(off) plt.tight_layout() plt.show() segmentation_comparison(segmentation_sample.jpg)8. 项目7综合应用 - 目标检测与识别8.1 项目架构设计本项目综合运用前面学到的技术实现一个完整的目标检测系统图像预处理去噪、增强目标检测轮廓分析、模板匹配目标识别特征匹配结果可视化8.2 完整系统实现class ObjectDetectionSystem: 目标检测系统 def __init__(self): self.filter ImageFilter() self.detector EdgeDetector() self.extractor ContourExtractor() self.feature_extractor FeatureExtractor(ORB) def preprocess_image(self, image): 图像预处理 # 去噪 denoised self.filter.gaussian_filter(image) # 对比度增强 lab cv2.cvtColor(denoised, cv2.COLOR_BGR2LAB) lab[:, :, 0] cv2.createCLAHE(clipLimit2.0).apply(lab[:, :, 0]) enhanced cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) return enhanced def detect_objects(self, image, min_area1000, max_area50000): 目标检测 # 边缘检测 edges self.detector.canny_edge(image, 30, 100) # 形态学操作闭合边缘 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) closed cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # 查找轮廓 contours, _ self.extractor.find_contours(closed) # 过滤轮廓 filtered_contours self.extractor.filter_contours_by_area( contours, min_area, max_area ) # 提取边界框 bounding_boxes [] for contour in filtered_contours: x, y, w, h cv2.boundingRect(contour) bounding_boxes.append((x, y, w, h)) return bounding_boxes, filtered_contours def recognize_objects(self, image, template_images): 目标识别模板匹配 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) results {} for name, template in template_images.items(): template_gray cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # 模板匹配 result cv2.matchTemplate(gray, template_gray, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(result) results[name] { confidence: max_val, location: max_loc, template_size: template_gray.shape[::-1] } return results def visualize_results(self, image, bounding_boxes, recognition_resultsNone): 可视化检测结果 result_image image.copy() # 绘制边界框 for i, (x, y, w, h) in enumerate(bounding_boxes): cv2.rectangle(result_image, (x, y), (xw, yh), (0, 255, 0), 2) cv2.putText(result_image, fObj{i1}, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 绘制识别结果 if recognition_results: for name, info in recognition_results.items(): if info[confidence] 0.8: # 置信度阈值 x, y info[location] w, h info[template_size] cv2.rectangle(result_image, (x, y), (xw, yh), (255, 0, 0), 2) cv2.putText(result_image, f{name}: {info[confidence]:.2f}, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) return result_image def object_detection_pipeline(image_path, template_pathsNone): 完整的目标检测流程 # 读取图像 image read_image(image_path) # 读取模板图像如果有 templates {} if template_paths: for name, path in template_paths.items(): templates[name] read_image(path) # 创建检测系统 system ObjectDetectionSystem() # 预处理 processed_image system.preprocess_image(image) # 目标检测 bounding_boxes, contours system.detect_objects(processed_image) # 目标识别 recognition_results None if templates: recognition_results system.recognize_objects(processed_image, templates) # 可视化结果 result_image system.visualize_results( processed_image, bounding_boxes, recognition_results ) # 显示结果 plt.figure(figsize(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title(原始图像) plt.axis(off) plt.subplot(1, 3, 2) plt.imshow(cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB)) plt.title(预处理后图像) plt.axis(off) plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB)) plt.title(检测结果) plt.axis(off) plt.tight_layout() plt.show() print(f检测到目标数量: {len(bounding_boxes)}) if recognition_results: for name, info in recognition_results.items(): print(f

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价