Извлеките пищевую тарелку эллипсной формы из изображения через Python - PullRequest
1 голос
/ 18 марта 2020

Food Plate

Идея состоит в том, чтобы извлечь тарелку, которая имеет форму эллипса.
Я попробовал метод HoughCircles из OpenCV, но он работает только для идеальные круги.
Я также попробовал метод hough_ellipse из skimage, но он занимает слишком много времени или я реализовал его неправильно.
Можно ли определить форму эллипса с помощью модуля OpenCV?

Какие существуют другие решения?

Пищевая тарелка:
enter image description here

1 Ответ

0 голосов
/ 19 марта 2020

Основной ключ для извлечения пластины использует cv2.adaptiveThreshold , но есть еще несколько этапов:

  • Преобразование в оттенки серого и применение адаптивного порога с относительно большим гауссовым значением.
  • Поиск подключенных компонентов (кластеров).
    Поиск самого большого кластера и создание нового образа только с самым большим кластером.
  • Используйте морфологическую операцию «открыть» для удаления некоторых артефактов.
  • Заполните пластину белыми пикселями (с помощью floodFill).
  • Найдите контуры и получите контур с максимальной площадью.
  • Нарисуйте контур с максимальным размером, чтобы создать маску.
    Нанесите маску на исходное изображение.

Нахождение эллипса по форме гораздо менее надежно ...

Вот код:

import numpy as np
import cv2
import imutils

img = cv2.imread('food_plate.jpg')

# Convert to Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Apply adaptive threshold with gaussian size 51x51
thresh_gray = cv2.adaptiveThreshold(gray, 255, adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C, thresholdType=cv2.THRESH_BINARY, blockSize=51, C=0)

#cv2.imwrite('thresh_gray.png', thresh_gray)

# Find connected components (clusters)
nlabel,labels,stats,centroids = cv2.connectedComponentsWithStats(thresh_gray, connectivity=8)

# Find second largest cluster (the cluster is the background):
max_size = np.max(stats[1:, cv2.CC_STAT_AREA])
max_size_idx = np.where(stats[:, cv2.CC_STAT_AREA] == max_size)[0][0]

mask = np.zeros_like(thresh_gray)

# Draw the cluster on mask
mask[labels == max_size_idx] = 255

# Use "open" morphological operation for removing some artifacts
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))

#cv2.imwrite('mask.png', mask)

# Fill the plate with white pixels
cv2.floodFill(mask, None, tuple(centroids[max_size_idx].astype(int)), newVal=255, loDiff=1, upDiff=1)

#cv2.imwrite('mask.png', mask)

# Find contours, and get the contour with maximum area
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)

c = max(cnts, key=cv2.contourArea)

# Draw contours with maximum size on new mask
mask2 = np.zeros_like(mask)
cv2.drawContours(mask2, [c], -1, 255, -1)

#cv2.imwrite('mask2.png', mask2)

img[(mask2==0)] = 0

# Save result
cv2.imwrite('img.jpg', img)

Результат:
enter image description here

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