OpenCV核心内容100讲【第86讲】计算机视觉在智能制造中的应用

文摘   2024-12-16 00:00   天津  

欢迎单击如下公众号“计算机视觉之,关注我

86 计算机视觉在智能制造中的应用

当今的智能制造领域不仅涉及到自动化机械和机器人控制,还依赖于计算机视觉等高技术手段,以提高生产效率和质量控制。本节将详细介绍计算机视觉在智能制造中的应用,从基础函数介绍到完整的示例代码,帮助读者扎实掌握相关知识点,最终能够在实际项目中灵活应用。

OpenCV中的基础函数

在涉及智能制造的计算机视觉应用中,有一些基础函数是必不可少的,本节将介绍以下几个关键函数:

  1. 边缘检测 (Canny)

    功能:检测图像中的边缘。

    语法:cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)

    参数:

    返回值:边缘检测后的图像。

  • image:输入图像,应为灰度图。
  • threshold1:第一个阈值。
  • threshold2:第二个阈值。
  • edges:输出边缘图像。
  • apertureSize:Sobel算子的大小。
  • L2gradient:计算梯度幅值的标志。
  • 轮廓发现 (findContours)

    功能:发现图像中的轮廓。

    语法:contours, hierarchy = cv2.findContours(image, mode, method)

    参数:

    返回值:轮廓信息和层次信息。

    • image:输入图像,应为二值图。
    • mode:轮廓检索模式。
    • method:轮廓近似方法。
  • 形态学操作 (MorphologyEx)

    功能:进行形态学变换,如膨胀和腐蚀等。

    语法:cv2.morphologyEx(src, op, kernel)

    参数:

    返回值:变换后的图像。

    • src:输入图像。
    • op:变换类型。
    • kernel:结构元素。
  • 模板匹配 (matchTemplate)

    功能:用以检测图像中的模板匹配情况。

    语法:cv2.matchTemplate(image, templ, method)

    参数:

    返回值:匹配结果。

    • image:待检测图像。
    • templ:模板图像。
    • method:匹配方法。

    示例一:边缘检测在智能制造中的应用

    在智能制造中,边缘检测常用于检测产品的轮廓和形状,从而进行质量控制与检测。以下示例展示了如何应用Canny边缘检测算法进行产品边缘的检测:

    import cv2
    import numpy as np

    # 读取图像
    image = cv2.imread('product.jpg', cv2.IMREAD_GRAYSCALE)

    # 应用高斯滤波减少噪声
    blurred = cv2.GaussianBlur(image, (55), 0)

    # 应用Canny边缘检测
    edges = cv2.Canny(blurred, 50150)

    # 显示结果
    cv2.imshow('Edges', edges)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    这一段代码首先读取产品图像,经过高斯滤波以减少噪声,再使用Canny函数进行边缘检测,最后显示检测结果。

    示例二:检测和分析产品的轮廓

    轮廓检测是质量控制的重要步骤,通过检测产品轮廓,可以判断产品是否出于正常状态。以下示例展示如何使用findContours来检测和分析产品的轮廓:

    import cv2
    import numpy as np

    # 读取图像
    image = cv2.imread('product.jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 转为二值图像
    _, binary = cv2.threshold(gray, 128255, cv2.THRESH_BINARY)

    # 发现轮廓
    contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 绘制轮廓
    cv2.drawContours(image, contours, -1, (02550), 2)

    # 显示结果
    cv2.imshow('Contours', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    在这个例子中,图像首先被转换为二值图像,然后通过findContours函数发现轮廓,最后通过drawContours函数绘制并显示轮廓。

    实战应用:部件的自动检测与分类

    在智能制造中,计算机视觉常被用于识别和分类不同种类的部件。以下示例展示如何进行这种自动检测与分类。

    螺丝的自动检测与分类

    步骤如下:

    1. 图像预处理
    2. 应用边缘检测
    3. 发现轮廓并分类
    import cv2
    import numpy as np

    # 读取图像
    image = cv2.imread('screws.jpg')

    # 转为灰度图像,并应用高斯模糊
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (55), 0)

    # 应用Canny边缘检测
    edges = cv2.Canny(blurred, 50150)

    # 发现轮廓
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 分类与绘制
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > 1000:
            cv2.drawContours(image, [contour], -1, (02550), 2)
        else:
            cv2.drawContours(image, [contour], -1, (00255), 2)

    # 显示结果
    cv2.imshow('Detected Screws', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    这个示例展示了如何通过边缘检测和轮廓发现功能来识别和分类不同大小的螺丝,面积大的螺丝用绿色标记,面积小的用红色标记。

    高级应用:基于模板匹配的自动化质量检测

    在智能制造中,模板匹配技术被广泛应用于检测产品是否符合设计要求。以下示例展示如何应用模板匹配技术进行螺丝缺陷检测。

    模板匹配示例

    # -*- coding: utf-8 -*-
    """
    Created on Sat May 25 21:35:57 2024

    @author: 李立宗
    """


    import cv2
    import numpy as np

    def non_max_suppression(boxes, overlap_thresh):
        if len(boxes) == 0:
            return []

        boxes = np.array(boxes).astype(float)
        pick = []
        x1 = boxes[:,0]
        y1 = boxes[:,1]
        x2 = boxes[:,2]
        y2 = boxes[:,3]
        area = (x2 - x1 + 1) * (y2 - y1 + 1)
        indices = np.argsort(y2)
        
        while len(indices) > 0:
            last = len(indices) - 1
            i = indices[last]
            pick.append(i)
            suppress = [last]
            
            for pos in range(last):
                j = indices[pos]
                xx1 = max(x1[i], x1[j])
                yy1 = max(y1[i], y1[j])
                xx2 = min(x2[i], x2[j])
                yy2 = min(y2[i], y2[j])
                w = max(0, xx2 - xx1 + 1)
                h = max(0, yy2 - yy1 + 1)
                overlap = float(w * h) / area[j]
                
                if overlap > overlap_thresh:
                    suppress.append(pos)
            
            indices = np.delete(indices, suppress)
        
        return boxes[pick].astype(int)

    image = cv2.imread('defective_screw.jpg')
    template = cv2.imread('screw_template.jpg', cv2.IMREAD_GRAYSCALE)
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    scales = [0.50.751.01.251.5]
    angles = np.arange(036030)
    rectangles = []

    for scale in scales:
        resized_template = cv2.resize(template, (00), fx=scale, fy=scale)
        for angle in angles:
            M = cv2.getRotationMatrix2D((resized_template.shape[1] // 2, resized_template.shape[0] // 2), angle, 1)
            rotated_template = cv2.warpAffine(resized_template, M, (resized_template.shape[1], resized_template.shape[0]))
            result = cv2.matchTemplate(gray_image, rotated_template, cv2.TM_CCOEFF_NORMED)
            loc = np.where(result >= 0.8)
            for pt in zip(*loc[::-1]):
                rectangles.append([pt[0], pt[1], pt[0] + rotated_template.shape[1], pt[1] + rotated_template.shape[0]])

    pick = non_max_suppression(rectangles, 0.3)

    def detect_defects(region, template):
        result = cv2.matchTemplate(region, template, cv2.TM_CCOEFF_NORMED)
        max_val = cv2.minMaxLoc(result)[1]
        return max_val < 0.8

    for (startX, startY, endX, endY) in pick:
        region = gray_image[startY:endY, startX:endX]
        best_match_template = None
        max_match_val = 0
        for scale in scales:
            resized_template = cv2.resize(template, (00), fx=scale, fy=scale)
            for angle in angles:
                M = cv2.getRotationMatrix2D((resized_template.shape[1] // 2, resized_template.shape[0] // 2), angle, 1)
                rotated_template = cv2.warpAffine(resized_template, M, (resized_template.shape[1], resized_template.shape[0]))
                if rotated_template.shape == region.shape:
                    match_val = cv2.matchTemplate(region, rotated_template, cv2.TM_CCOEFF_NORMED)
                    max_val = cv2.minMaxLoc(match_val)[1]
                    if max_val > max_match_val:
                        best_match_template = rotated_template
                        max_match_val = max_val
        if best_match_template is not None and not detect_defects(region, best_match_template):
            cv2.rectangle(image, (startX, startY), (endX, endY), (02550), 2)

    cv2.imshow('Detected Defects', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    这段代码展示了如何利用模板匹配技术检测图像中的缺陷部分,通过设置模板匹配的相似度阈值,来定位并绘制出无缺陷区域。

    使用形状匹配:

    import cv2
    import numpy as np

    def read_image(file_path):
        # 读取图像
        image = cv2.imread(file_path)
        if image is None:
            raise ValueError(f"图像文件 {file_path} 未找到或无法读取。")
        return image

    def preprocess_image(image):
        # 转换为灰度图像
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # 应用高斯模糊以减少噪声
        blurred = cv2.GaussianBlur(gray, (55), 0)
        # 二值化图像
        _, binary = cv2.threshold(blurred, 60255, cv2.THRESH_BINARY)
        return binary

    def find_contours(binary_image):
        # 检测轮廓
        contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        return contours

    def match_shapes(template_contour, input_contours):
        matched_contours = []
        for contour in input_contours:
            match_score = cv2.matchShapes(template_contour, contour, cv2.CONTOURS_MATCH_I1, 0.0)
            if match_score > 0.8:  # 阈值设置为0.1,值越低匹配度越高
                matched_contours.append(contour)
        return matched_contours

    def draw_contours(image, contours):
        for contour in contours:
            cv2.drawContours(image, [contour], -1, (00255), 2)  # 用红色绘制缺陷轮廓
        return image

    def main():
        # 读取模版和待检测图像
        template_image = read_image('screw_template.jpg')
        defect_image = read_image('defective_screw.jpg')

        # 预处理图像
        template_binary = preprocess_image(template_image)
        defect_binary = preprocess_image(defect_image)

        # 找到轮廓
        template_contours = find_contours(template_binary)
        defect_contours = find_contours(defect_binary)

        if len(template_contours) == 0:
            raise ValueError("模板图像中未检测到任何轮廓。")
        if len(defect_contours) == 0:
            raise ValueError("待检测图像中未检测到任何轮廓。")

        # 使用第一个轮廓作为模板
        template_contour = template_contours[0]

        # 匹配轮廓并找出缺陷
        defective_contours = match_shapes(template_contour, defect_contours)

        # 在图像上绘制缺陷部分
        result_image = draw_contours(defect_image.copy(), defective_contours)

        # 显示结果
        cv2.imshow('Defective Screw Detection', result_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    if __name__ == "__main__":
        main()

    总结

    本节详细介绍了计算机视觉在智能制造中的应用,涵盖了从基础函数语法到实际应用的全面内容。通过多个实例的详细讲解,大家可以掌握如何在不同场景下应用计算机视觉技术进行边缘检测、轮廓检测、对象分类以及模板匹配,实现智能制造中的自动化质量检测和控制。这些知识和技能为智能制造提供了强大的技术支持,帮助提高生产效率和产品质量。



    这里简单介绍了一些基本知识点,更细致的内容请参考:

    • 李立宗,OpenCV轻松入门(第2版),电子工业出版社,2023

    • 李立宗,计算机视觉40例(从入门到深度学习:OpenCV-Python),电子工业出版社,2022


    在公众号【计算机视觉之光】回复 【OpenCV模拟试卷】获得《数字图像处理(OpenCV-Python》模拟试卷及参考答案。
    在公众号【计算机视觉之光】回复 【Python试卷】获得《Python程序设计》模拟试卷及参考答案。

    单击【阅读原文】参加OpenCV-Python课程学习。

    在本公众号【计算机视觉之光】回复关键字“叮叮当当”获取更多的Python学习资料。

    欢迎单击如下公众号“计算机视觉之光”,关注我




    计算机视觉之光
    电子工业出版社优秀作者,代表作《OpenCV轻松入门》,《计算机视觉40例》。
     最新文章