利用Python从图像中提取椭圆形状的食物盘

利用Python从图像中提取椭圆形状的食物盘,python,opencv,image-processing,computer-vision,object-detection,Python,Opencv,Image Processing,Computer Vision,Object Detection,其想法是提取椭圆形状的板。 我尝试了OpenCV中的HoughCircles方法,但它只适用于完美的圆。 我还尝试了skimage中的hough_eliple方法,但它花费的时间太长,或者我用了错误的方法实现了它。 是否可以使用OpenCV模块检测椭圆形状 还有什么其他解决办法 食物盘: 提取板的主键是使用,但还有几个阶段: 转换为灰度并应用具有相对较大高斯噪声的自适应阈值 查找连接的组件(群集)。 查找最大的群集,并仅使用最大的群集创建新映像 使用“开放”形态学操作移除一些瑕疵 用白色像素填

其想法是提取椭圆形状的板。
我尝试了OpenCV中的
HoughCircles
方法,但它只适用于完美的圆。
我还尝试了
skimage
中的
hough_eliple
方法,但它花费的时间太长,或者我用了错误的方法实现了它。
是否可以使用OpenCV模块检测椭圆形状

还有什么其他解决办法

食物盘:

提取板的主键是使用,但还有几个阶段:

  • 转换为灰度并应用具有相对较大高斯噪声的自适应阈值
  • 查找连接的组件(群集)。
    查找最大的群集,并仅使用最大的群集创建新映像
  • 使用“开放”形态学操作移除一些瑕疵
  • 用白色像素填充平板(使用泛光填充)
  • 找到等高线,得到面积最大的等高线
  • 以最大尺寸绘制轮廓以创建遮罩。
    在原始图像上应用遮罩
通过形状找到椭圆,鲁棒性要差得多

代码如下:

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)
结果:

谢谢您的解释+代码。我是OpenCV的新手,非常感谢您的努力。顺便说一句,代码是特定于此场景的。这个想法是在所有这些图像(食品摄影)中提取盘子形状,即基本上在图像中找到椭圆/圆。我认为找到椭圆形状的第一步是将前景与背景分离(例如使用
adaptiveThreshold
)。不要期望得到堆栈溢出中困难问题的通用解决方案。你没有表现出自己解决问题的任何努力(你没有发布代码),在大多数情况下,这样的问题永远不会得到回答。