Обнаружение кругов на изображении - преобразование Хафа, обработка изображений - PullRequest
0 голосов
/ 21 января 2019

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

Исходное изображение:

enter image description here

и результат будет примерно таким:

enter image description here

Я использую преобразование Хафа в Opencv2, но я не могу найти эти круги. У меня есть радио радио обоих кругов. Итак, моя идея состоит в том, чтобы обнаружить верхний круг (закрашенный красным) и с этим соотношением получить второй круг.

Мой код на python:

###############################
#Read Image
###############################
image = cv2.imread('Celulas/celulas.jpg')
origin=image
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.GaussianBlur(image, (5, 5), 0)

sobelX = cv2.Sobel(image, cv2.CV_64F, 1, 0)
sobelY = cv2.Sobel(image, cv2.CV_64F, 0, 1)
sobelX = np.uint8(np.absolute(sobelX))
sobelY = np.uint8(np.absolute(sobelY))
sobelCombined = cv2.bitwise_or(sobelX, sobelY)

image = sobelCombined
binary_global = image > threshold_otsu(image)

img_bin=binary_global
img_8=bin2uint8(img_bin)
image=img_8      


###############################
#Circle detection
###############################
height, width = image.shape

circles = cv2.HoughCircles(image,cv2.HOUGH_GRADIENT,.3,20,
                           param1=100,param2=100,minRadius=int(min(width,height)/3)
                                maxRadius=int(min(width,height)))

circles = np.uint16(np.around(circles))

cimg=origin
for i in circles[0,:]:
    cv2.circle(cimg,(i[0],i[1]),i[2],(255,0,0),1) #DRAW ALL CIRCLES IN BLUE
    cv2.circle(cimg,(i[0],i[1]),2,(255,0,0),1)


###############################
#FIND HIGHER CIRCLE
###############################
max_index=0
max_i=circles[0,max_index,2]
for indx, i in enumerate(circles[0,:]):
    print(i)
    print("----")
    if i[2]>max_i:
        max_i=i[2]
        max_index=indx   #indx of higher circle
        print("MAXIMO:", max_i)

circle_max=max_i
x_max=circles[0,max_index,0]
y_max=circles[0,max_index,1]
r_max=circles[0,max_index,2]


cv2.circle(cimg,(x_max,y_max),r_max,(0,0,255),1) #DRAW HIGHER CIRCLE IN RED
cv2.circle(cimg,(x_max,y_max),2,(0,0,255),3)

###############################
#FIND INSIDE CIRCLE
###############################
encontrado=0
relacion=.9105  #the relationship between the radios is 91.05%
tol=0.01
ponderacion = 0.3
while (1):
    r_min_menor = (r_max * relacion) * (1 - tol)
    r_min_mayor = (r_max * relacion) * (1 + tol)
    x_min_menor = x_max * (1 - tol) * ponderacion
    x_min_mayor = x_max * (1 + tol) * ponderacion
    y_min_menor = y_max * (1 - tol) * ponderacion
    y_min_mayor = y_max * (1 + tol) * ponderacion
    for indx, m in enumerate(circles[0,:]):
        if indx !=max_index: #para que no compare con el mismo circulo
           if m[2]>r_min_menor and m[2]<r_min_mayor and m[0]>x_min_menor 
                               and m[0]<x_min_mayor and m[1]>y_min_menor
                               and m[1]<y_min_mayor: 
               circle_min=m
               print("Encontro un circulo")
               cv2.circle(cimg,(m[0],m[1]),m[2],(0,255,0),1)
               cv2.circle(cimg,(m[0],m[1]),2,(0,255,0),3)
               cv2.imshow('detected circles',cimg)
               cv2.waitKey(0)
               if encontrado == 0:
                   encontrado=1
    if encontrado:
        break
    tol=tol*1.05

cimg=origin
cv2.circle(cimg,(x_min,y_min),r_min,(0,255,0),1) #DRAW INSIDE CIRCLE IN GREEN
cv2.circle(cimg,(x_min,y_min),2,(0,255,0),3)

И полученный результат был:

enter image description here

enter image description here

...