【小白也能懂】基于OpenCV的螺母尺寸测量系统开发Vol.1

封面图片:《英雄联盟》角色------黑默丁格,来自皮城的大发明家,始终热爱科学和发明

前言

最近在开发一款基于OpenCV的螺母尺寸测量系统,作为我的毕业设计,说人话就是:教计算机认识螺母,并且get"我的眼睛就是尺"技能,通过摄像头拍摄螺母图像,就能测量出尺寸参数;希望给对机器视觉感兴趣的技术爱好者们提供一些帮助

初步效果示意图,可检测出多数螺母尺寸

目前已实现基础功能,但还存在诸多待改进之处,本文主要分享软件部分的核心实现思路,后续将推出代码详解篇;为控制篇幅,Python环境配置等基础内容暂不涉及,若有需要可在评论区留言

代码结构

markdown 复制代码
螺母测量系统
│
├── config.py          # 参数配置文件
├── image_processor.py # 图像处理模块
├── nut_analyzer.py    # 螺母分析模块
├── utils.py           # 工具函数模块
└── main.py            # 主程序入口

1.配置文件(config.py

这个文件就像系统的"控制面板",集中存放所有可调节参数。当需要调整检测灵敏度时,只需修改这里的数值,无需改动其他代码

python 复制代码
class Config:  #定义了一个叫Config的类
    # 图像预处理参数
    GAUSSIAN_KSIZE = (7, 7)    # 高斯模糊核大小,7x7 内核用于降噪
    CANNY_THRESH1 = 10         # Canny 边缘检测低阈值,控制边缘敏感度
    CANNY_THRESH2 = 80        # Canny 边缘检测高阈值,连接边缘
    
    # 轮廓筛选参数
    MIN_AREA = 1000            # 最小轮廓面积,过滤小噪声
    MAX_AREA = 10000           # 最大轮廓面积,过滤过大物体
    
    # 标定参数(需根据实际标定结果修改)
    PIXELS_PER_MM = 15.5       # 每毫米像素数(通过标定板计算)

2.图像处理模块(image_processor.py)

这个模块就像"流水线工人",负责:

  1. 把彩色图转成灰度图(方便处理)
  2. 用"模糊滤镜"消除图像噪点
  3. 用"边缘检测"找出物体边界
  4. 通过"修补操作"闭合小裂缝
  5. 最后用"轮廓追踪"画出零件形状
python 复制代码
import cv2 #导入一个叫OpenCV的库
from config import Config #从config.py文件里导入Config类

class ImageProcessor:
    @staticmethod #静态方法,不用创建实例便可直接使用类
    def preprocess(image): #定义了一个名为"preprocess"的方法,类中的函数称为方法
        """图像预处理流水线"""
        # 转换为灰度图
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #颜色空间转换函数,参数1是需要转换的图片,参数2是转换成何种格式。
        
        # 高斯模糊降噪
        blurred = cv2.GaussianBlur(gray, Config.GAUSSIAN_KSIZE, 0) #高斯核大小为5x5,X轴方向上的高斯核的标准差为0
        
        # Canny边缘检测
        edges = cv2.Canny(blurred, Config.CANNY_THRESH1, Config.CANNY_THRESH2) #输入图像,低阈值,高阈值
        
        # 形态学操作(闭合小孔)
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #创建一个3X3的矩形结构元素
        closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) #对edges在3X3的矩形结构元素里使用闭运算
        
        return closed

    @staticmethod
    def find_contours(processed_image):
        """轮廓检测方法"""
        contours, _ = cv2.findContours( #contours是返回的轮廓列表,_ 是另一个返回值,但在这里不使用。
            processed_image,  #该参数表示输入的图像
            cv2.RETR_EXTERNAL, #参数 mode 决定了轮廓的提取方式,这里是只检测外轮廓
            cv2.CHAIN_APPROX_SIMPLE #参数 method 决定了如何表达轮廓,这里是压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标
        )
        return contours

3.螺母分析模块(nut_analyzer.py)

这个模块就像"质检员",负责:

  1. 筛掉太小的杂乱轮廓(比如螺丝、划痕)
  2. 用几何方法计算:
  • 画最小包围圆测直径
  • 画最小矩形测长宽
  1. 把像素尺寸转换成实际毫米单位
python 复制代码
import cv2
import numpy as np
from config import Config

class NutAnalyzer:
    @staticmethod
    def filter_contours(contours):
        """筛选有效螺母轮廓"""
        valid_contours = []
        for cnt in contours:
            area = cv2.contourArea(cnt)  # 计算轮廓面积
            if Config.MIN_AREA < area < Config.MAX_AREA: # 筛选面积在范围内的轮廓
                valid_contours.append(cnt)
        return valid_contours

    @staticmethod
    def calculate_dimensions(contour):
        """计算螺母尺寸"""
        # 找最小外接圆,计算出中心点坐标、半径
        (x, y), radius = cv2.minEnclosingCircle(contour) 
        
        # 找最小面积矩形,获取宽高
        rect = cv2.minAreaRect(contour)
        (w, h) = rect[1] # 提取矩形宽高
        distance_across_flats_pixels = min(w,h) #取最小面积矩形的较小边长作为跨平距离
        
        # 转换实际尺寸(毫米)
        diameter_mm = distance_across_flats_pixels / Config.PIXELS_PER_MM
        width_mm = w / Config.PIXELS_PER_MM
        height_mm = h / Config.PIXELS_PER_MM
        
        #将直径、宽度和高度的数值四舍五入到小数点后两位
        return {
            "diameter": round(diameter_mm, 2),
            "width": round(width_mm, 2),
            "height": round(height_mm, 2)
        }

4.工具模块(utils.py

这个模块就像"报告生成器",把检测结果用绿色框线标出,并在图片上显示测量数值。

python 复制代码
import cv2

def draw_measurements(image, contours, dimensions):
    """可视化标注工具"""
    for cnt, dim in zip(contours, dimensions): #遍历每个轮廓和对应的尺寸。
        # 使用 cv2.drawContours绘制轮廓,颜色为绿色,线宽为2。
        cv2.drawContours(image, [cnt], 0, (0, 255, 0), 2)
        
        # 标注文字,显示该轮廓的直径信息
        text = f"across_flats:{dim['diameter']}mm"
        x, y, _, _ = cv2.boundingRect(cnt) #通过 cv2.boundingRect获取轮廓的边界框,用于确定文本的放置位置
        cv2.putText(image, text, (x, y-10),  #使用 cv2.putText 在图像上添加直径文本,文本颜色为红色,字体大小为0.7,线宽为2。
                   cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
    return image #返回绘制完标注的图像。

5.主程序(main.py

主程序像"工厂老板",按步骤指挥各个模块运作:

  1. 进货(读取图片)
  2. 粗加工(对图片进行预处理)
  3. 精加工(找螺母轮廓)
  4. 质量筛检(过滤不合格的轮廓)
  5. 测量尺寸
  6. 打标签(可视化)
  7. 出货(显示结果)
python 复制代码
import cv2 #导入OpenCV库
from image_processor import ImageProcessor #从"image_processor"库中导入ImageProcessor类
from nut_analyzer import NutAnalyzer #从"nut_analyzer"库中导入NutAnalyzer类
from utils import draw_measurements #从"utils"库中导入draw_measurements函数

def main(): #定义main函数
    # 1. 读取输入
    image = cv2.imread("Nut.jpg") #读取全称为"Nut.jpg"的图像
    
    # 2. 图像预处理
    processed = ImageProcessor.preprocess(image) #调用ImageProcessor类里的preprocess()方法
    
    # 3. 轮廓检测
    contours = ImageProcessor.find_contours(processed) #调用ImageProcessor类里的find_contours()方法
    
    # 4. 筛选螺母轮廓
    valid_contours = NutAnalyzer.filter_contours(contours) #调用NutAnalyzer类里的filter_contours()方法
    
    # 5. 尺寸计算
    dimensions = [NutAnalyzer.calculate_dimensions(cnt) #调用NutAnalyzer类里的calculate_dimensions()方法
                 for cnt in valid_contours]
    
    # 6. 可视化结果
    result_image = draw_measurements(image.copy(), valid_contours, dimensions) #调用utils.py里的draw_measurements()函数
    
    # 7. 显示输出
    cv2.imshow("Measurement Result", result_image) #给窗口命名为"Measurement Result"并显示图像

if __name__ == "__main__":
    main() # 相当于启动"检测流水线"的开关

系统工作原理示意图

可优化细节

  • 图片中9个螺母只能识别出7个
  • 无法在图像中显示中文注释
  • 没有区分圆形螺母和六角螺母
  • 目前只能显示六角螺母的跨平距离,可以再加上对角直径、孔直径等参数
  • 可以尝试用函数进行动态调参cv2.createTrackbar

本项目的完整代码库后续会在GitHub上开源(地址将会发到评论区),欢迎各位技术爱好者在评论区留言,共同探讨改进方案;下期将深入解析代码以及OpenCV库,敬请期待!

相关推荐
byxdaz1 小时前
CUDA编程之OpenCV与CUDA结合使用
人工智能·opencv·计算机视觉
YueiL4 小时前
OpenCV 颜色空间:原理与操作指南
python·opencv
WenGyyyL4 小时前
使用OpenCV和MediaPipe库——增强现实特效(在手腕添加虚拟手表)
人工智能·opencv·计算机视觉·ar·cv·mediapipe
挣扎与觉醒中的技术人1 天前
OpenCV视频解码全流程详解
人工智能·深度学习·opencv·计算机视觉·ffmpeg·音视频
WenGyyyL1 天前
使用OpenCV和MediaPipe库——驼背检测(姿态监控)
人工智能·python·opencv·算法·计算机视觉·numpy
jndingxin2 天前
OpenCV计算摄影学(16)调整图像光照效果函数illuminationChange()
人工智能·opencv·计算机视觉
花花鱼2 天前
opencv 阈值threshold 二值化,反二值化,截断,阈值取零,阈值反取零 python版实现
python·opencv·计算机视觉
挣扎与觉醒中的技术人2 天前
OpenCV视频解码性能优化十连击(实测帧率提升300%)
人工智能·opencv·ffmpeg·音视频·实时音视频·视频编解码·外包转型
jndingxin2 天前
OpenCV计算摄影学(18)平滑图像中的纹理区域同时保留边缘信息函数textureFlattening()
人工智能·opencv·计算机视觉
深图智能2 天前
海思Hi3516DV300交叉编译opencv
人工智能·opencv·计算机视觉