基于Python计算特定暗区域(黑条)的平均宽度
嘿,这个需求我之前帮别人处理过,用Python结合OpenCV就能轻松搞定!我给你拆解下步骤,再附上可直接用的代码,你可以根据自己的图像情况调整细节~
实现思路与步骤
核心思路是通过图像处理把黑条和背景分离,检测黑条的轮廓后计算宽度,最后批量统计所有图像的平均宽度:
- 图像预处理:把彩色图转灰度,再加个模糊过滤小噪声,让黑条的边界更清晰。
- 二值化分割:自动或手动设置阈值,把黑条从背景里单独分出来(黑条会变成高亮区域,方便后续检测)。
- 轮廓检测:找出所有黑条的轮廓,用边界框计算每个黑条的宽度。
- 批量统计:遍历所有图像,收集所有黑条的宽度,最后计算整体平均值。
具体代码实现
首先得安装依赖库,打开终端跑这个命令:
pip install opencv-python numpy
然后是完整代码:
import cv2 import numpy as np import os def calculate_black_bar_widths(image_path, bar_direction='horizontal'): """计算单张图像中黑条的平均宽度""" # 加载图像并转灰度 img = cv2.imread(image_path) if img is None: print(f"无法加载图像: {image_path}") return 0, [] gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊去噪,避免小干扰点被误判 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 自动阈值二值化(OTSU算法),把黑条转为白色区域方便检测 _, thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 查找黑条的轮廓(只找最外层轮廓) contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) widths = [] for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) # 根据黑条方向选择宽度(横向取w,纵向取h) current_width = w if bar_direction == 'horizontal' else h # 过滤掉过小的噪声点(阈值根据你的图像调整) if current_width > 8: widths.append(current_width) return np.mean(widths) if widths else 0, widths def batch_process_images(image_dir, bar_direction='horizontal'): """批量处理目录下的所有图像,计算整体平均宽度""" all_bar_widths = [] # 遍历目录里的所有图像文件 for filename in os.listdir(image_dir): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): img_path = os.path.join(image_dir, filename) single_avg, widths = calculate_black_bar_widths(img_path, bar_direction) if widths: all_bar_widths.extend(widths) print(f"处理完成 {filename}: 单图黑条平均宽度 = {single_avg:.2f}") if not all_bar_widths: print("所有图像中均未检测到黑条,请检查图像或调整参数") return None overall_average = np.mean(all_bar_widths) print(f"\n=== 统计结果 ===") print(f"所有图像黑条的总平均宽度: {overall_average:.2f} 像素") return overall_average # ---------------------- 使用示例 ---------------------- # 1. 测试单张图像 # avg_width, _ = calculate_black_bar_widths("test_image.jpg", bar_direction='horizontal') # print(f"单图黑条平均宽度: {avg_width:.2f} 像素") # 2. 批量处理整个目录的图像 # 替换成你的图像文件夹路径 batch_process_images("your_image_folder_path", bar_direction='horizontal')
关键细节调整
- 黑条方向:如果你的黑条是纵向的,把
bar_direction参数改成vertical即可。 - 噪声过滤阈值:代码里的
current_width >8是过滤小噪声的,你可以根据自己图像中黑条的最小宽度调整数值。 - 手动阈值:如果OTSU自动阈值效果不好,你可以替换二值化代码为手动设置阈值,比如:
这里的_, thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY_INV)60是阈值,数值越小,越容易把暗区域识别为黑条,你可以根据图像实际情况调整。
内容的提问来源于stack exchange,提问作者Luxo_Jr
相关产品推荐
相关产品推荐

