python-圆形检测-封闭轮廓检测

圆形检测

通过python做圆形检测,基本都是一个套路,利用霍夫检测的思路,借用cv包的HoughCircles进行检测,这里要注意该函数的参数,不同的参数应对不同的业务场景,参数说明如下表
在这里插入图片描述
我经常修改的参数为minDist,param2,minRadius,maxRadius。一定不要犯懒,都挨个去理解,去试。
贴上我的代码和业务数据:代码也是我在别的地方抄的,随便百度就能找到
在这里插入图片描述

import cv2

img = cv2.imread('O:/work/circleimg/1009/yuan4.png')
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

th2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \
                            cv2.THRESH_BINARY, 11, 2)

ret, thresh1 = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)

canny = cv2.Canny(thresh1, 40, 80)

canny = cv2.blur(canny, (3, 3))

# 霍夫变换圆检测
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 1000, param1=10, param2=35, minRadius=40, maxRadius=150)
# 输出检测到圆的个数
print(len(circles[0]))

for circle in circles[0]:
    if (circle[2] >= 100):
        continue
    x = int(circle[0])
    y = int(circle[1])
    r = int(circle[2])
    img = cv2.circle(img, (x, y), r, (0, 0, 255), -1)
cv2.imshow('res', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

闭合轮廓检测

因为业务场景要求不一定是圆形可以当作圆,闭合的曲线也可以作为圆,所以就探索了新的思路。这里我贴一个链接,应该能给你一些启发思路
我的思路来源于对cv.findContours函数的参数和返回值的发现。

  1. 该函数的第个参数(轮廓的检索方式)可选很多,参数说明,因为考虑到实际的场景,封闭的圆一定在轮廓上存在层级关系的,所以我这里选择了cv.RETR_TREE,这样该函数的第二个返回值hierarchy就会保存层级关系,层级关系解释
  2. 通过层级关系以及轮廓数量,就可以筛选掉很多图片了,但是也有特例,就是数字6和9通过图片可以看到,这两张图片和封闭的轮廓一毛一样,而且层级关系也是相同的,于是通过第三参数(轮廓的近似办法)cv.CHAIN_APPROX_SIMPLE参数说明cv.findContours函数的第一个返回值进行判断。我判断的依据是:如果是曲线是闭合轮廓且没有其他的分支(反例,6和9),那么拟合该曲线的内外轮廓的坐标数差值相比于其他的曲线是更小的。经过实际证明确实是这样,不同的业务有不同的思路。上代码:
import cv2 as cv
import os
import numpy as np
# 定义圆形轮廓层级结构
x = [[[-1, -1, 1,-1], [-1, -1, 2,0], [-1, -1, -1,1]]]
x = np.array(x)
def circle(j):
    src = cv.imread('O:/work/circleimg/1009/'+str(j))
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    _, thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
    contours, hierarchy = cv.findContours(gray, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
    # 轮廓数量为3 且符合x标准
    print(j)
    if len(contours)==3 and (hierarchy == x).all():
        if abs(len(contours[1])-len(contours[2]))<40:
            print("有缘")
        else:
            print("无缘")
    else:
        print("无缘")
    cv.drawContours(src,contours,-1,(0,0,255),2)
    cv.imshow("edged", src)
    cv.waitKey(0)
    cv.destroyAllWindows()

for i in os.listdir('O:/work/circleimg/1009/'):
    circle(i)

简要说明:

  • 变量x是我的数据图像取得固定圆形封闭轮廓层级关系,你的可能有所不同需要调试一番
  • 图像预处理也需要注意,如果有需要可进行7x7的中值滤波
#最后欢迎邮箱讨论:zhangmaoker@163.com
### 使用Python实现弹孔检测的新方法 为了开发一个新的弹孔检测算法,可以从现有的图像处理技术和机器学习技术出发。一种有效的方式是结合传统计算机视觉方法与现代深度学习模型。 #### 利用OpenCV进行预处理 对于输入的图片,在应用任何复杂的检测逻辑之前,先执行基本的预处理操作是非常重要的。这通常涉及灰度转换、噪声去除以及边缘增强等步骤。例如: ```python import cv2 import numpy as np def preprocess_image(image_path): img = cv2.imread(image_path, 0) # 将图像读取为灰度模式 # 应用高斯模糊减少噪音 blurred_img = cv2.GaussianBlur(img, (5, 5), 0) # Canny 边缘检测器用于提取轮廓信息 edges = cv2.Canny(blurred_img, threshold1=30, threshold2=100) return edges ``` 此部分借鉴了已有的图像增强经验[^1],其中提到的各种滤波器可以帮助改善原始图像质量,从而提高后续特征提取的效果。 #### 运用形态学操作优化二值化后的图像 在完成初步过滤之后,可以进一步采用形态学膨胀腐蚀(Opening/Closing Operations),以清理可能存在的细小干扰物并填充封闭区域内的间隙。这些技巧有助于更精确地定位圆形物体——即潜在的弹孔位置。 ```python kernel = np.ones((3, 3), dtype=np.uint8) opened_edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel) closed_edges = cv2.morphologyEx(opened_edges, cv2.MORPH_CLOSE, kernel) ``` 上述代码片段展示了如何利用形态学运算来改进边界定义的质量[^3]。 #### 霍夫变换寻找圆心坐标 一旦获得了较为清晰的边缘图,则可以通过霍夫圆变换找到疑似弹孔的位置及其半径大小。这种方法特别适合用来识别具有明显边界的圆形结构。 ```python circles = cv2.HoughCircles(closed_edges, method=cv2.HOUGH_GRADIENT, dp=1.2, minDist=20, param1=50, param2=30, minRadius=5, maxRadius=50) if circles is not None: detected_circles = np.round(circles[0, :]).astype(int) for (x, y, r) in detected_circles: cv2.circle(original_image, center=(x, y), radius=r, color=(0, 255, 0), thickness=2) ``` 这段程序来源于先前关于霍夫变换的应用实例[^5],能够有效地从经过前序处理过的图像中挑选出符合条件的圆形对象。 #### 结合卷积神经网络提升准确性 如果希望构建更加鲁棒性的解决方案,还可以考虑引入CNN架构来进行端到端的学习过程。通过大量标注好的样本集训练特定类型的分类器或者回归器,使得系统能够在复杂背景下准确无误地区分真实弹孔与其他相似形状之间的差异。 ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense model = Sequential([ Conv2D(32, (3, 3), activation='relu', input_shape=(height, width, channels)), MaxPooling2D(pool_size=(2, 2)), Conv2D(64, (3, 3), activation='relu'), MaxPooling2D(pool_size=(2, 2)), Flatten(), Dense(128, activation='relu'), Dense(num_classes, activation='softmax') ]) ``` 这里给出的是一个简单的两层卷积神经网络框架[^4],可以根据实际需求调整层数和参数配置,以便更好地适应具体应用场景下的数据特点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值