python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python OpenCV形状检测

Python OpenCV实现图像形状检测

作者:傻啦嘿哟

图像形状检测是计算机视觉领域中的一项关键技术,广泛应用于工业自动化、机器人视觉、医学图像处理等多个领域,本文将介绍如何使用Python OpenCV实现图像形状检测,需要的可以参考下

图像形状检测是计算机视觉领域中的一项关键技术,广泛应用于工业自动化、机器人视觉、医学图像处理等多个领域。本文将详细介绍如何使用Python和OpenCV库实现图像形状检测,通过简洁明了的步骤和代码示例,帮助你快速掌握这一技能。

一、环境准备

在开始之前,确保你的电脑上已经安装了Python和OpenCV库。你可以通过以下命令来安装OpenCV库:

pip install opencv-python

同时,确保你能够编写和运行Python代码,并熟悉基本的图像处理概念。

二、读取和预处理图像

读取图像

使用OpenCV的cv2.imread()函数读取图像文件。例如,读取一张包含不同形状的图像:

import cv2
 
# 读取图像
img = cv2.imread('shapes.png')

灰度化

将彩色图像转换为灰度图像,以简化后续处理。使用cv2.cvtColor()函数:

# 转换为灰度图像
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

滤波去噪

使用高斯模糊来去除图像中的噪声。高斯模糊是一种常用的图像处理技术,可以平滑图像并减少噪声干扰。使用cv2.GaussianBlur()函数:

# 高斯模糊
blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0)

三、边缘检测

边缘检测是形状检测的重要步骤,它可以帮助我们找到图像中的轮廓。使用Canny边缘检测算法,该算法是一种常用的边缘检测算法,具有良好的边缘检测效果。使用cv2.Canny()函数:

# Canny边缘检测
edges = cv2.Canny(blurred_img, 50, 150)

四、查找轮廓

使用cv2.findContours()函数查找图像中的轮廓。该函数会返回轮廓点集、层次结构和轮廓的近似方法。我们主要关注轮廓点集:

# 查找轮廓
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

五、绘制轮廓

为了可视化检测到的轮廓,我们可以使用cv2.drawContours()函数在原图像上绘制轮廓:

# 绘制轮廓
contour_img = img.copy()
cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)

六、形状分类

根据轮廓的顶点数目、面积、周长等特征,我们可以对检测到的形状进行分类。以下是一个简单的形状分类示例:

for contour in contours:
    # 计算轮廓面积
    area = cv2.contourArea(contour)
    
    # 计算轮廓周长
    perimeter = cv2.arcLength(contour, True)
    
    # 近似轮廓为多边形
    epsilon = 0.02 * perimeter
    approx = cv2.approxPolyDP(contour, epsilon, True)
    
    # 获取轮廓顶点数目
    num_vertices = len(approx)
    
    # 根据顶点数目判断形状
    shape = 'Unknown'
    if num_vertices == 3:
        shape = 'Triangle'
    elif num_vertices == 4:
        # 判断是否为正方形或矩形
        x, y, w, h = cv2.boundingRect(approx)
        aspect_ratio = w / float(h)
        if 0.95 < aspect_ratio < 1.05:
            shape = 'Square'
        else:
            shape = 'Rectangle'
    elif num_vertices == 5:
        shape = 'Pentagon'
    elif num_vertices == 6:
        shape = 'Hexagon'
    else:
        # 对于顶点数目大于6的形状,可以根据周长面积比等特征进一步分类
        # 例如,圆形可以通过周长面积比接近某个阈值来判断
        if 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter > 0.8 and 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter < 1.2:
            shape = 'Circle'
        else:
            shape = 'Other Polygon'
    
    # 在图像上标注形状名称和顶点数目
    M = cv2.moments(contour)
    if M['m00'] != 0:
        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])
    else:
        cX, cY = 0, 0
    
    cv2.putText(contour_img, f'{shape} ({num_vertices} vertices)', (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
    cv2.drawContours(contour_img, [approx], -1, (0, 0, 255), 2)

七、显示结果

最后,使用cv2.imshow()函数显示处理后的图像:

# 显示结果图像
cv2.imshow('Shape Detection', contour_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

八、完整代码示例

以下是完整的代码示例,将上述步骤整合在一起:

import cv2
 
# 读取图像
img = cv2.imread('shapes.png')
 
# 转换为灰度图像
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
# 高斯模糊
blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0)
 
# Canny边缘检测
edges = cv2.Canny(blurred_img, 50, 150)
 
# 查找轮廓
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
# 绘制轮廓并分类形状
 
 
contour_img = img.copy()
for contour in contours:
    # 计算轮廓面积
    area = cv2.contourArea(contour)
    
    # 计算轮廓周长
    perimeter = cv2.arcLength(contour, True)
    
    # 近似轮廓为多边形
    epsilon = 0.02 * perimeter
    approx = cv2.approxPolyDP(contour, epsilon, True)
    
    # 获取轮廓顶点数目
    num_vertices = len(approx)
    
    # 根据顶点数目判断形状
    shape = 'Unknown'
    if num_vertices == 3:
        shape = 'Triangle'
    elif num_vertices == 4:
        # 判断是否为正方形或矩形
        x, y, w, h = cv2.boundingRect(approx)
        aspect_ratio = w / float(h)
        if 0.95 < aspect_ratio < 1.05:
            shape = 'Square'
        else:
            shape = 'Rectangle'
    elif num_vertices == 5:
        shape = 'Pentagon'
    elif num_vertices == 6:
        shape = 'Hexagon'
    else:
        # 对于顶点数目大于6的形状,可以根据周长面积比等特征进一步分类
        # 例如,圆形可以通过周长面积比接近某个阈值来判断
        if 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter > 0.8 and 4 * 3.14 * (area / 3.14) ** 0.5 / perimeter < 1.2:
            shape = 'Circle'
        else:
            shape = 'Other Polygon'
    
    # 在图像上标注形状名称和顶点数目
    M = cv2.moments(contour)
    if M['m00'] != 0:
        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])
    else:
        cX, cY = 0, 0
    
    # 绘制形状名称和顶点数目
    cv2.putText(contour_img, f'{shape} ({num_vertices} vertices)', (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
    
    # 绘制轮廓(近似多边形)
    cv2.drawContours(contour_img, [approx], -1, (0, 0, 255), 2)
 
# 显示结果图像
cv2.imshow('Shape Detection', contour_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

九、总结

本文介绍了如何使用Python和OpenCV库实现图像形状检测。通过环境准备、图像预处理、边缘检测、轮廓查找、绘制轮廓及形状分类等步骤,展示了完整的图像形状检测流程。利用高斯模糊、Canny边缘检测和轮廓近似等技术,实现了对图像中不同形状的有效检测与分类。通过示例代码,读者可以快速掌握图像形状检测的基本方法和技巧,为工业自动化、机器人视觉等领域的实际应用提供有力支持。

到此这篇关于Python OpenCV实现图像形状检测的文章就介绍到这了,更多相关Python OpenCV形状检测内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文