python - 从 findContours 中删除某些点,以便从 fitEllipse 获得更好的结果

标签 python opencv curve-fitting contour ellipse

我想将椭圆拟合到图片中部分损坏的物体上。 (这里的图片只是为了说明而简化的示例!)

椭圆形物体受损的图像

image

通过这样做

def sort(n):
    return n.size

Image = cv2.imread('acA2500/1.jpg', cv2.IMREAD_GRAYSCALE)

#otsu binarization
_, binary = cv2.threshold(Image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

#invert binary image for opencv findContours
inverse_binary = cv2.bitwise_not(binary)

#find contours
contours, _ = cv2.findContours(inverse_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

#sort contours by length
largest_contours = sorted(contours, key=sort, reverse=True)

#fit ellipse
contour = largest_contours[0]
ellipse = cv2.fitEllipseDirect(contour)

我得到的结果不是很令人满意。

Result of cv2.findContours and cv2.fitEllipse

因此,我构建了这个循环来消除不在椭圆上的轮廓点。

contour = largest_contours[0]
newcontour = np.zeros([1, 1, 2])
newcontour = newcontour.astype(int)
for coordinate in contour:
    if coordinate[0][0] < 600:
        newcontour = np.insert(newcontour, 0, coordinate, 0)
newellipse = cv2.fitEllipse(newcontour)

得到这个结果,这很好。

Result after trimming the contour points

问题是,我必须在短时间内做很多这样的事情。到目前为止,这还没有达到预期的速度。

有没有更好/更快/更好的方法来修剪轮廓点?由于我没有很多编码经验,我很乐意在这里找到一些帮助:-)

编辑:

我编辑了示例图片,现在很清楚,不幸的是,cv2.minEnendingCircle 方法不起作用。

现在的图片也展示了我为什么对轮廓进行排序。在我的真实代码中,我将一个椭圆拟合到三个最长的轮廓,然后通过不同的例程查看我想使用哪一个。

如果我不修剪轮廓并手动为cv2.fitEllipse选取轮廓,则代码需要大约0.5s。通过轮廓修剪和三次 cv2.fitEllipse 大约需要 2s。可能只需要1s

最佳答案

如果对象是圆形,则可以在轮廓上使用cv2.minEnendingCircle来捕获它。

#!/usr/bin/python3
# 2019/02/13 08:50 (CST)
# https://stackoverflow.com/a/54661012/3547485

import cv2
img = cv2.imread('test.jpg')

## Convert to grayscale and threshed it
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, threshed = cv2.threshold(gray, 100, 255, cv2.THRESH_OTSU|cv2.THRESH_BINARY_INV)

## Find the max outers contour
cnts = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
cv2.drawContours(img, cnts, -1, (255, 0, 0), 2, cv2.LINE_AA)

## Use minEnclosingCircle
(cx,cy),r = cv2.minEnclosingCircle(cnts[0])
cv2.circle(img, (int(cx), int(cy)), int(r), (0, 255, 0), 1, cv2.LINE_AA)

## This it
cv2.imwrite("dst.jpg", img)

这是我的结果。

enter image description here

关于python - 从 findContours 中删除某些点,以便从 fitEllipse 获得更好的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54659887/

相关文章:

c++ - 如何在cpp中将jpg图像转换为pgm格式

c++ - 如何在 OpenCV 中锐化图像

python - 如何找到各个 x 和 y 值的拟合参数

python - 在python中计算表面拟合后3D偏差的均方根

python - 使用键列表从字典中选择值

python - 为什么我在索引字节时会得到一个 int?

opencv - OpenCV phase() 函数在这种边缘情况下是否正常工作?

r - 将多个峰拟合到数据集并在 R 中提取单个峰信息

python - 将记事本中的数据导入到python编辑器中

python - 为什么计算器会崩溃