首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测圆缺陷?

如何检测圆缺陷?
EN

Stack Overflow用户
提问于 2022-11-21 18:40:16
回答 3查看 83关注 0票数 -1

有没有办法判断一个圆是否有这样的缺陷?圆度不起作用。还是有办法消除它们?

代码语言:javascript
复制
    perimeter = cv2.arcLength(cnts[0],True)
    area = cv2.contourArea(cnts[0])
    roundness = 4*pi*area/(perimeter*perimeter)
    print("Roundness:", roundness)
EN

回答 3

Stack Overflow用户

发布于 2022-11-21 20:25:19

“圆度”测量对周长的精确估计很敏感。cv2.arcLength()所做的是添加每个多边形边的长度,它严重高估了轮廓的长度。我认为这是这个措施对你不起作用的主要原因。有了一个更好的周长估计器,你就会得到有用的结果。

另一种可能更有用的度量是“圆度”,定义为半径的变异系数。简而言之,计算每个多边形顶点(即轮廓点)到质心的距离,然后确定这些距离的变异系数(== std /平均值)。

我编写了一个快速Python脚本,从OpenCV轮廓开始计算它:

代码语言:javascript
复制
import cv2
import numpy as np

# read in OP's example image, making sure we ignore the red arrow
img = cv2.imread('jGssp.png')[:, :, 1]
_, img = cv2.threshold(img, 127, 255, 0)

# get the contour of the shape
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contour = contours[0][:, 0, :]

# add the first point as the last, to close it
contour = np.concatenate((contour, contour[0, None, :]))

# compute centroid
def cross_product(v1, v2):
    """2D cross product."""
    return v1[0] * v2[1] - v1[1] * v2[0]

sum = 0.0
xsum = 0.0
ysum = 0.0
for ii in range(1, contour.shape[0]):
    v = cross_product(contour[ii - 1, :], contour[ii, :])
    sum += v
    xsum += (contour[ii - 1, 0] + contour[ii, 0]) * v
    ysum += (contour[ii - 1, 1] + contour[ii, 1]) * v

centroid = np.array([ xsum, ysum ]) / (3 * sum)

# Compute coefficient of variation of distances to centroid (==circularity)
d = np.sqrt(np.sum((contour - centroid) ** 2, axis=1))
circularity = np.std(d) / np.mean(d)
票数 4
EN

Stack Overflow用户

发布于 2022-11-25 16:00:56

这让我想到了一个类似的问题。您可以计算形状的签名。签名可以定义为,对于形状边界的每个像素,该像素与形状中心之间的距离。

对于一个完美的圆,从边界到中心的距离应该是恒定的(在一个理想的连续世界中)。当缺陷出现在圆的边缘(凹痕或过度)时,理想的常量线会变成一条摇摆的曲线,在缺陷上会有很大的变化。

例如,用FFT来检测这些变化是相当容易的,这样就可以量化缺陷的重要性。

您可以将此解决方案扩展到任意给定的形状。如果你的理想形状是正方形,你可以计算签名,这会给你一些正弦曲线。缺陷将以同样的方式出现在曲线上,并且可以用与圆相同的逻辑来检测。

我不能给你一个代码示例,因为项目是为一个公司的项目,但这个想法仍然存在。

票数 0
EN

Stack Overflow用户

发布于 2022-11-25 21:52:16

这里有一种在Python/OpenCV中实现这一功能的方法。

  • 读取输入
  • 白色阈值(移除红色箭头)
  • 应用Hough圆
  • 绘制阈值图像上的圆圈以供比较
  • 从圆圈参数在黑色背景上画一个白色填充的圆圈。
  • 得到阈值图像与绘制的圆图像的区别。
  • 应用开放的形态学将圆环从原始圆的不规则边界上移除。
  • 将上一幅图像中的白色像素数计算为“关闭缺陷量”。

输入:

代码语言:javascript
复制
import cv2
import numpy as np

# Read image
img = cv2.imread('circle_defect.png')
hh, ww = img.shape[:2]

# threshold on white to remove red arrow
lower = (255,255,255)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)

# get Hough circles
min_dist = int(ww/5)
circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 1, minDist=min_dist, param1=150, param2=15, minRadius=0, maxRadius=0)
print(circles)

# draw circles on input thresh (without red arrow)
circle_img = thresh.copy()
circle_img = cv2.merge([circle_img,circle_img,circle_img])
for circle in circles[0]:
    # draw the circle in the output image, then draw a rectangle
    # corresponding to the center of the circle
    (x,y,r) = circle
    x = int(x)
    y = int(y)
    r = int(r)
    cv2.circle(circle_img, (x, y), r, (0, 0, 255), 1)

# draw filled circle on black background
circle_filled = np.zeros_like(thresh)
cv2.circle(circle_filled, (x,y), r, 255, -1)

# get difference between the thresh image and the circle_filled image
diff = cv2.absdiff(thresh, circle_filled)

# apply morphology to remove ring
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
result = cv2.morphologyEx(diff, cv2.MORPH_OPEN, kernel)

# count non-zero pixels
defect_count = np.count_nonzero(result)
print("defect count:", defect_count)

# save results
cv2.imwrite('circle_defect_thresh.jpg', thresh)
cv2.imwrite('circle_defect_circle.jpg', circle_img)
cv2.imwrite('circle_defect_circle_diff.jpg', diff)
cv2.imwrite('circle_defect_detected.png', result)

# show images
cv2.imshow('thresh', thresh)
cv2.imshow('circle_filled', circle_filled)
cv2.imshow('diff', diff)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

没有红箭的输入:

根据输入绘制的红色圆圈:

从HoughCircle圈:

差异:

消除差异:

文本结果:

代码语言:javascript
复制
defect count: 500
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74523496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档