Я пытаюсь определить круговой край блюда на этом изображении и обрезать изображение для обоих кругов.
Исходное изображение:
и результат будет примерно таким:
Я использую преобразование Хафа в 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)
И полученный результат был: