Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 改进椭圆拟合算法_Python_Opencv_Numpy - Fatal编程技术网

Python 改进椭圆拟合算法

Python 改进椭圆拟合算法,python,opencv,numpy,Python,Opencv,Numpy,我希望我能在改进椭圆拟合方法方面得到一些帮助。我正在考虑尝试使用RANSAC风格的方法,但我不确定这是否是正确的方向。在我应该开始的方向上的任何帮助都将不胜感激,即使这只是对我的边缘发现的一个改进 我已经研究这个问题一段时间了,但进展不大。我认为主要的问题是图像的质量,但我只能做我现在所能做的 我目前正在测试的方法是对图像使用边缘检测,然后尝试在找到的边缘周围拟合椭圆。下面的图片将突出我的主要问题,这是我的方法处理噪音非常差 原始图像: Canny边缘检测后: 椭圆拟合后: 下面是我使用的

我希望我能在改进椭圆拟合方法方面得到一些帮助。我正在考虑尝试使用RANSAC风格的方法,但我不确定这是否是正确的方向。在我应该开始的方向上的任何帮助都将不胜感激,即使这只是对我的边缘发现的一个改进

我已经研究这个问题一段时间了,但进展不大。我认为主要的问题是图像的质量,但我只能做我现在所能做的

我目前正在测试的方法是对图像使用边缘检测,然后尝试在找到的边缘周围拟合椭圆。下面的图片将突出我的主要问题,这是我的方法处理噪音非常差

原始图像:

Canny边缘检测后:

椭圆拟合后:

下面是我使用的代码。对于Canny边缘检测,我找到了一些值,目前正在静态使用它们。这是从网上下载的代码,我已经修改过了,现在有点不对劲

#!/usr/bin/python
import cv2
import numpy as np
import sys
from numpy.linalg import eig, inv

# param is the result of canny edge detection
def process_image(img):
    # for every pixel in the image:
    for (x,y), intensity in np.ndenumerate(img):
        # if the pixel is part of an edge:
        if intensity == 255:
            # determine if the edge is similar to an ellipse
            ellipse_test(img, x, y)

def ellipse_test(img, i, j):
    #poor coding practice but what I'm doing for now
    global output, image
    i_array = []
    j_array = []
    # flood fill i,j while storing all unique i,j values in arrays
    flood_fill(img, i, j, i_array, j_array)
    i_array = np.array(i_array)
    j_array = np.array(j_array)
    if i_array.size >= 10:
        #put those values in a numpy array
        #which can have an ellipse fit around it
        array = []
        for i, elm in enumerate(i_array):
          array.append([int(j_array[i]), int(i_array[i])])
        array = np.array([array])
        ellp = cv2.fitEllipse(array)
        cv2.ellipse(image, ellp, (0,0,0))
        cv2.ellipse(output, ellp, (0,0,0))

def flood_fill(img, i, j, i_array, j_array):
    if img[i][j] != 255:
        return
    # store i,j values
    i_array.append(float(i))
    j_array.append(float(j))
    # mark i,j as 'visited'
    img[i][j] = 250
    # flood_fill adjacent and diagonal pixels

    (i_max, j_max) = img.shape

    if i - 1 > 0 and j - 1 > 0:
        flood_fill(img, i - 1, j - 1, i_array, j_array)
    if j - 1 > 0:
        flood_fill(img, i, j - 1, i_array, j_array)
    if i - 1 > 0:
        flood_fill(img, i - 1, j, i_array, j_array)
    if i + 1 < i_max and j + 1 < j_max:
        flood_fill(img, i + 1, j + 1, i_array, j_array)
    if j + 1 < j_max:
        flood_fill(img, i, j + 1, i_array, j_array)
    if i + 1 < i_max:
        flood_fill(img, i + 1, j, i_array, j_array)
    if i + 1 < i_max and j - 1 > 0:
        flood_fill(img, i + 1, j - 1, i_array, j_array)
    if i - 1 > 0 and j + 1 < j_max:
        flood_fill(img, i - 1, j + 1, i_array, j_array)

image = cv2.imread(sys.argv[1], 0)
canny_result = cv2.GaussianBlur(image, (3,3), 0)
canny_result = cv2.Canny(canny_result, 107, 208,
    apertureSize=3, L2gradient=False)

#output is a blank images which the ellipses are drawn on
output = np.zeros(image.shape, np.uint8)
output[:] = [255]

cv2.waitKey(0)
cv2.namedWindow("Canny result:", cv2.WINDOW_NORMAL)
cv2.imshow('Canny result:', canny_result)
print "Press any key to find the edges"
cv2.waitKey(0)
print "Now finding ellipses"

process_image(canny_result)
print "Ellipses found!"
cv2.namedWindow("Original image:", cv2.WINDOW_NORMAL)
cv2.imshow('Original image:', image)

cv2.namedWindow("Output image:", cv2.WINDOW_NORMAL)
cv2.imshow("Output image:", output)
cv2.waitKey(0)
#/usr/bin/python
进口cv2
将numpy作为np导入
导入系统
来自numpy.linalg进口eig,inv
#param是canny边缘检测的结果
def过程图像(img):
#对于图像中的每个像素:
对于(x,y),强度单位为np.ndenumerate(img):
#如果像素是边的一部分:
如果强度=255:
#确定边是否类似于椭圆
椭圆_检验(img,x,y)
def椭圆试验(img,i,j):
#糟糕的编码实践,但我现在在做什么
全局输出,图像
i_数组=[]
j_数组=[]
#整体填充i,j,同时在数组中存储所有唯一的i,j值
溢流填充(img、i、j、i_阵列、j_阵列)
i_数组=np.array(i_数组)
j_数组=np.数组(j_数组)
如果i_array.size>=10:
#将这些值放入numpy数组中
#它周围可以有一个椭圆
数组=[]
对于i,枚举中的elm(i_数组):
append([int(j_数组[i]),int(i_数组[i]))
array=np.array([array])
ellp=cv2.fit椭圆(阵列)
cv2.椭圆(图像,ellp,(0,0,0))
cv2.椭圆(输出,ellp,(0,0,0))
def溢流填充(img、i、j、i_阵列、j_阵列):
如果img[i][j]!=255:
返回
#存储i,j值
i_数组.append(float(i))
j_数组.append(float(j))
#mark i,j作为“访问”
img[i][j]=250
#整体填充相邻和对角像素
(i_max,j_max)=img.shape
如果i-1>0和j-1>0:
洪水填充(img、i-1、j-1、i\U阵列、j\U阵列)
如果j-1>0:
洪水填充(img、i、j-1、i_阵列、j_阵列)
如果i-1>0:
洪水填充(img、i-1、j、i_阵列、j_阵列)
如果i+10:
洪水填充(img、i+1、j-1、i_阵列、j_阵列)
如果i-1>0且j+1
以下是我尝试过的,我使用
explate
scipy.ndimage
进行一些处理:

import cv2
import numpy as np

image = cv2.imread("ellipse.jpg", 0)

bimage = cv2.GaussianBlur(image, (3, 3), 0)
edge_image = cv2.Canny(bimage, 107, 208,
    apertureSize=3, L2gradient=False)

img2 = cv2.dilate(edge_image, np.ones((3, 3)), iterations=3)
dis_image = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)

import scipy.ndimage as ndimage
labels, count = ndimage.label(img2)

for lab, idx in enumerate(ndimage.find_objects(labels.astype(int)), 1):
    sy = idx[0].start
    sx = idx[1].start
    y, x = np.where(labels[idx] == lab)
    ellp = cv2.fitEllipse(np.column_stack((x+sx, y+sy)))
    cv2.ellipse(dis_image, ellp, (0, 0, 255))
以下是输出: