2014-01-16 2 views
1

Я надеюсь, что смогу помочь в улучшении метода подбора эллипса. Я думаю о попытке использовать метод стиля RANSAC, но я не уверен, что это правильное направление. Любая помощь по направлению, в котором я должна начать, была бы весьма признательна, даже если это просто улучшение на моем краевом нахождении.Улучшение моего алгоритма аппроксимации эллипса

Я некоторое время работаю над этой проблемой, и я не очень продвигаюсь вперед. Я думаю, что основная проблема заключается в качестве изображений, но я могу работать только с тем, что у меня есть сейчас.

Мой текущий метод, который я тестирую, - использовать обнаружение края на изображении, а затем попытаться установить эллипсы вокруг найденных краев. На приведенных ниже снимках будет показана моя главная проблема, которая заключается в том, что мой метод очень плохо работает с шумом.

Исходное изображение: http://i.imgur.com/usygfXw.jpg

После обнаружения Канни фронта: http://i.imgur.com/K7XDcVL.png

После Ellipse Место: http://i.imgur.com/bN0lNIq.jpg

Ниже приведен код, который я использую. Для обнаружения края 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) 

ответ

2

Вот что я пытался, я использую dilate и 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)) 

здесь выход:

enter image description here

Смежные вопросы