Python 如何使用OpenCV在几乎圆形的孔中找到各种圆弧的不同中心?

Python 如何使用OpenCV在几乎圆形的孔中找到各种圆弧的不同中心?,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,我有一张洞的照片。我现在假设这个洞不是一个完美的圆,因此我需要找到作品尺寸的变化。现在我想取三个30度的弧,求出这些弧的中心和圆的中心之间的距离(我将使用Hough圆来求),然后取这些值的平均值。这就是我研究所需要的。我附上一个样本照片的一个洞,我已经钻。任何帮助都会有帮助 如果你有一个洞,你可以在你的“物体”后面使用特定颜色的背景。因此,分割实际形状应该不是问题: 然后遍历所有点,找到最远的一对(这样就可以找到直径)。比如说,你可以找到你要找的圆的中心。刚刚做了一个快速测试: 抱歉,没有要

我有一张洞的照片。我现在假设这个洞不是一个完美的圆,因此我需要找到作品尺寸的变化。现在我想取三个30度的弧,求出这些弧的中心和圆的中心之间的距离(我将使用Hough圆来求),然后取这些值的平均值。这就是我研究所需要的。我附上一个样本照片的一个洞,我已经钻。任何帮助都会有帮助


如果你有一个洞,你可以在你的“物体”后面使用特定颜色的背景。因此,分割实际形状应该不是问题:

然后遍历所有点,找到最远的一对(这样就可以找到直径)。比如说,你可以找到你要找的圆的中心。刚刚做了一个快速测试:


抱歉,没有要显示的代码。我这里没有使用OpenCV,但是您说任何帮助都是有用的:)

一个想法是先设置阈值,然后找到轮廓,并使用最大的轮廓区域进行过滤。从这里我们可以找到中心
(x,y)
点和半径。这是以绿色突出显示的最大轮廓

现在,我们只需找到轮廓周围的最小封闭圆来确定中心点。这是结果

(x,y)
坐标

176.53846740722656 174.33653259277344
代码

这只是计算质心的许多可能方法之一

  • 1.利用时机
  • 2使用凸性缺陷和拟合椭圆消除异常值
  • 使用新数据点的矩(消除异常值)

  • 结果

  • 进一步改进:

    通过迭代轮廓消除异常值,并检测圆弧和非圆弧


首先检测内轮廓并将其分割成圆弧,然后将每个圆弧拟合到圆上以找到中心。@Ziri你能给我一些如何拟合圆部分的指针吗?你能详细说明一下吗?谢谢,一旦你有了圆弧,你就可以应用RANSAC圆拟合:@Ziri分割圆弧时也有问题吗?我能想到的唯一方法是,取一个像下面这样的封闭圆,然后将它分成30度增量,然后取这些增量,但这不会给我们实际圆的弧,而不是实际弧的弧吗?我不确定这部分。若你们需要精确的结果,那个么圆并不是你们想要的。我建议使用从质心到边缘的距离,从内轮廓中消除这些缺陷(非圆弧)区域,然后把它分割成圆弧。你能用这个函数找到一个以上的最小封闭圆吗?不,这种方法是假设图像中只有一个孔图像中只有一个孔,但孔不是完全圆形的,因此我需要问题中描述的圆弧来获取我的数据。我想我不明白你的问题是正确的。能否添加预期的输出图像?是否有关于如何检测圆弧和非圆弧的链接。我唯一能想到的就是测量轮廓上一个点的距离,并将其与前一个点进行比较,看看误差是否可以接受。我相信有更好的办法
import cv2
import numpy as np

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)

for c in cnts:
    (x,y), radius = cv2.minEnclosingCircle(c)
    cv2.circle(image,(int(x),int(y)),int(radius),(35,255,12),3)
    cv2.circle(image,(int(x),int(y)),1,(35,255,12),2)
    print(x,y)
    break

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()
import cv2
import numpy as np
import math
import random

ConvexityDefectPoint = []

# load image as color to draw
img = cv2.imread('YourImagePath\\test.jpg' , 
cv2.IMREAD_COLOR )
#convert to gray
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#threshold
ret,thresh1= cv2.threshold(gray,29,255,cv2.THRESH_BINARY_INV)
contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#find the biggest contour
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
#draw the bigest contour
cv2.drawContours(img,biggest_contour,-1,(0,255,0),3)
# compute the center of the contour using moment
M = cv2.moments(biggest_contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# draw the centroid
cv2.circle(img, (cX, cY), 7, (0, 255, 255), -1)
#Get convexity defect points
hull = cv2.convexHull(biggest_contour,returnPoints = False)
defects = cv2.convexityDefects(biggest_contour,hull)

for i in range(defects.shape[0]):
    s,e,f,d = defects[i,0]
    start = tuple(biggest_contour[s][0])
    end = tuple(biggest_contour[e][0])
    far = tuple(biggest_contour[f][0])
    ConvexityDefectPoint.append(far)
    #cv2.line(img,start,end,[0,255,0],2)
    cv2.circle(img,far,5,[0,0,255],-1)

# fit ellipse to the selected points.
(x, y), (MA, ma), angle = cv2.fitEllipse(np.array(ConvexityDefectPoint))
# draw the ellipse center
cv2.circle(img, (int(x), int(y)), 7, (0, 0, 255), -1)

# Draw the center using moment ( outliers eliminated)
M = cv2.moments(np.array(ConvexityDefectPoint))
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cv2.circle(img, (cX, cY), 7, (0, 255, ), -1)

cv2.imshow('Display',img)
cv2.waitKey(0)