【问题标题】:Extract ellipse shape food plate from image through Python通过Python从图像中提取椭圆形食物盘
【发布时间】:2020-03-18 20:24:11
【问题描述】:

Food Plate

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

还有哪些其他解决方案?

餐盘:

【问题讨论】:

    标签: python opencv image-processing computer-vision object-detection


    【解决方案1】:

    提取盘子的主要关键是使用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)
    

    结果:

    【讨论】:

    • 感谢解释+代码。我对 OpenCV 很陌生,所以感谢您的努力。顺便说一句,代码特定于这种情况。这个想法是在所有这些图像(食品摄影)中提取盘子形状,即基本上找到图像中的椭圆/圆。
    • 我认为寻找椭圆形状的第一阶段是将前景与背景分开(例如使用adaptiveThreshold)。不要期望在 Stack Overflow 中获得针对难题的通用解决方案。您没有表现出自己解决问题的任何努力(您没有发布代码),并且在大多数情况下,此类问题从未得到解答。
    猜你喜欢
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    相关资源
    最近更新 更多