OpenCV检测圆形东西是否存在缺口?

文章目录


前言

想了挺久,一直没解决这个问题。后面勉强解决了。


一、试过的方法

1.想用圆度来解决,后来发现圆度差值很小,完整的圆圆度0.89,然后有缺角的圆圆度0.88。

2.想用面积来解决,但是图片中每个圆大小不是一致的,是有一些差别的,也没办法。

3.多边形拟合、凸包都不合适。

4.想使用角点的数量来确定,发现也是不行。看下图

二、最终使用的方法

1.先极坐标变换

代码如下(示例):

python 复制代码
import cv2
import os

# 设置文件夹路径
folder_path = r"E:\VSCODE_PY\CAPCode\Posong\cap_2"

# 遍历文件夹中的图像文件
for file_name in os.listdir(folder_path):
    if file_name.endswith(".jpg"):
        # 读取图像并转换为灰度图像
        image_path = os.path.join(folder_path, file_name)
        image = cv2.imread(image_path)
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        # 进行极坐标变换
        polar_image = cv2.linearPolar(gray, (gray.shape[1]//2, gray.shape[0]//2), gray.shape[1]//2+10, cv2.WARP_FILL_OUTLIERS)

        # 进行边缘检测
        edges = cv2.Canny(polar_image, 50, 150)

        # 保存处理后的图像
        output_path = os.path.join(folder_path, "polar_" + file_name)
        cv2.imwrite(output_path, polar_image)

极坐标的中心点可以根据实际情况设置一下。

2.计算斜率

代码如下(示例):

python 复制代码
import os
import cv2
import numpy as np

# 设置最小间距阈值
min_distance = 10

# 遍历cap_8文件夹内的所有图片
for filename in os.listdir(r'E:\VSCODE_PY\CAPCode\Posong\cap_8'):
    if filename.endswith('.jpg'):
        # 读取图像并进行灰度化处理
        image = cv2.imread(os.path.join(r'E:\VSCODE_PY\CAPCode\Posong\cap_8', filename))
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        # 进行边缘检测
        edges = cv2.Canny(gray, 50, 150)

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

        # 创建一个空白图像,用于绘制轮廓
        contour_image = np.zeros_like(image)

        # 绘制轮廓
        cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)

        # 查找角点
        corners = cv2.cornerHarris(gray, 2, 3, 0.04)

        # 标记角点
        threshold = 0.45 * corners.max()  # 调整阈值
        corners = cv2.dilate(corners, None)
        image[corners > threshold] = [0, 0, 255]

        # 计算任意两个角点之间的斜率
        corner_points = np.argwhere(corners > threshold)
        slopes = []
        for i in range(len(corner_points)):
            for j in range(i+1, len(corner_points)):
                x1, y1 = corner_points[i]
                x2, y2 = corner_points[j]
                distance = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
                if distance >= min_distance:
                    if x2 - x1 == 0:
                        slope = float('inf')
                    else:
                        slope = (y2 - y1) / (x2 - x1)
                    slopes.append(slope)

        # 处理无穷大和无穷小的情况
        slopes = [slope for slope in slopes if slope != float('inf') and slope != float('-inf')]
        slopes.sort()

        # 输出最大斜率和最小斜率的绝对值
        if len(slopes) >= 2:
            max_slope = max(abs(slopes[-2]), abs(slopes[1]))
            min_slope = min(abs(slopes[-2]), abs(slopes[1]))
        else:
            max_slope = float('-inf')
            min_slope = float('inf')

        print("图片{}的最大斜率的绝对值:".format(filename), max_slope)
        print("图片{}的最小斜率的绝对值:".format(filename), min_slope)

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

角点稍微多,要先设置一下任意2个角点的斜率必须大于最小间距。

这样可以求出每一张图片的斜率绝对值最大和最小值,即看下凸起部分是不是影响到了曲线的斜率。


总结

完成。

相关推荐
Watermelo6173 分钟前
从DeepSeek大爆发看AI革命困局:大模型如何突破算力囚笼与信任危机?
人工智能·深度学习·神经网络·机器学习·ai·语言模型·自然语言处理
Donvink5 分钟前
【DeepSeek-R1背后的技术】系列九:MLA(Multi-Head Latent Attention,多头潜在注意力)
人工智能·深度学习·语言模型·transformer
计算机软件程序设计11 分钟前
深度学习在图像识别中的应用-以花卉分类系统为例
人工智能·深度学习·分类
Ainnle17 分钟前
企业级RAG开源项目分享:Quivr、MaxKB、Dify、FastGPT、RagFlow
人工智能·开源
小天努力学java1 小时前
AI赋能传统系统:Spring AI Alibaba如何用大模型重构机票预订系统?
人工智能·spring
Fuweizn1 小时前
在工业生产中,物料搬运环节至关重要,搬运机器人开启新篇章
人工智能·智能机器人·复合机器人
技术员阿伟1 小时前
《AI赋能星际探索:机器人如何开启宇宙新征程!》
人工智能
技术员阿伟1 小时前
《解锁AI密码,机器人精准感知环境不再是梦!》
人工智能
AL.千灯学长3 小时前
DeepSeek接入Siri(已升级支持苹果手表)完整版硅基流动DeepSeek-R1部署
人工智能·gpt·ios·ai·苹果vision pro
LCG元3 小时前
大模型驱动的围术期质控系统全面解析与应用探索
人工智能