OpenCV cv2.ellipse расширение для сложных случаев - PullRequest
0 голосов
/ 30 марта 2020

У меня есть маска (не двоичная, а значения в диапазоне 0-255):

enter image description here

Я использую cv2.fitEllipse, например:

xy_arr = np.argwhere(mask>0)
xy_arr = xy_arr[:,::-1]
(center_x, center_y), (MA, ma), angle = cv2.fitEllipse(xy_arr)
cv2.ellipse(draw_image, (int(center_x), int(center_y)), (int(MA / 2), int(ma / 2)), int(angle), 0, 360, (0, 0, 255))
cv2.circle(draw_image, (int(center_x), int(center_y)), radius=1, color=(0, 0, 255), thickness=1)

Результат:

enter image description here

Однако ожидаемый результат:

enter image description here

Вопросы:

  1. Можно ли использовать промежуточные значения маски (промежуточные значения в диапазоне 0-255, а не только двоичную маску)
  2. Как преодолеть проблема с левым хвостом, можно ли его обрезать по кривизне?

1 Ответ

2 голосов
/ 30 марта 2020

Вот один из способов использования морфологии для уменьшения хвоста в Python / OpenCV.

  • Чтение ввода
  • Преобразование в серый
  • Порог
  • Применить открытую морфологию, чтобы сгладить хвост
  • Получить ненулевые точки
  • Получить выпуклые точки корпуса
  • Установить эллипс на выпуклые точки корпуса
  • Нарисуйте эллипс на входе
  • Сохранить результаты

Вход:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('blob.png')
hh, ww = img.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold to binary and invert
thresh = cv2.threshold(gray, 252, 255, cv2.THRESH_BINARY)[1]

# apply morphology open to smooth out tail
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
smoothed = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
smoothed = cv2.morphologyEx(smoothed, cv2.MORPH_DILATE, kernel)

# fit ellipse on smoothed image
points = np.column_stack(np.where(smoothed.transpose() > 0))
hull = cv2.convexHull(points)
((centx,centy), (width,height), angle) = cv2.fitEllipse(hull)

# draw ellipse on input image
result = img.copy()
cv2.ellipse(result, (int(centx),int(centy)), (int(width/2),int(height/2)), angle, 0, 360, (0,0,255), 1)

cv2.imshow('image', img)
cv2.imshow('thresh', thresh)
cv2.imshow('smoothed', smoothed)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('blob_thresh.png', thresh)
cv2.imwrite('blob_smoothed.png', smoothed)
cv2.imwrite('blob_ellipses.png', result)


Пороговое изображение:

enter image description here

Морфологическое сглаженное изображение:

enter image description here

Результирующее изображение эллипса:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...