【问题标题】:Obtaining object contour inside bounding box获取边界框内的对象轮廓
【发布时间】:2020-12-08 17:50:32
【问题描述】:

Input image

我想检测肉的轮廓。我已经为肉类训练了一个对象检测模型。模型的输出如下所示,边界框坐标为左上角的 (44,34) 和右下角的 (321,348)。

Detected meat

如何通过 opencv 或其他图像处理库根据此输出分割肉的轮廓?

【问题讨论】:

  • 您认为深度估计正确吗?牛肉下面的表面看起来垂直于相机并且是平坦的,但这在深度估计中没有表示出来。
  • See here. 这不是 100% 正确的,但我在平面上测试了一本书的正常轮廓检测,平均了书的轮廓和平面内的深度值(参考),然后线性计算书的深度,然后是它的厚度。这导致了 5% 的错误。
  • 好的,你只想提取牛肉的轮廓吗?我认为这可以在没有深度估计的情况下实现。
  • 是的!如果有帮助,我还训练了一个模型来检测肉类(边界框,而不是分割)。
  • 我已经通过使用 Otsu 的阈值去除伪影取得了进展,但这仍然不够。根据要求更新了问题。

标签: python opencv image-processing


【解决方案1】:

您可以使用 Grabcut [1] 算法从边界框中提取片段。

Grabcut 尝试将像素聚集成两组,在边界框之外和内部,同时惩罚与具有相似颜色的相邻像素的标签不一致。

例如:

import cv2 
import numpy as np

im = cv2.imread('beef.jpg')
mask = np.zeros(im.shape[:2], np.uint8)

bgd_model = np.zeros((1, 65), np.float64)
fgd_model = np.zeros((1, 65), np.float64)

rect = (30, 25, 30 + 318, 25 + 350)  # (x, y, w, h)
cv2.grabCut(im, mask, rect, bgd_model, fgd_model, 10, cv2.GC_INIT_WITH_RECT)                      

mask = np.where((mask == cv2.GC_BGD) | (mask == cv2.GC_PR_BGD), 0, 1).astype(np.uint8)

contour, _= cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im, contour, -1, (0, 255, 0)) 

cv2.imwrite("output.png", im) 

[1] Rother、Carsten、Vladimir Kolmogorov 和 Andrew Blake。 “GrabCut”使用迭代图形切割的交互式前景提取。” ACM Transactions on Graphics (TOG) 23.3 (2004): 309-314。

【讨论】:

  • 太棒了!谢谢。
【解决方案2】:

您面临的问题是由于顶部的阴影,这使得肉在某些地方与背景一样暗。

您可以尝试对图像的红色部分进行二值化,然后通过形态闭合去除孔洞,但这会稍微损坏轮廓。

【讨论】:

  • 这看起来非常棒。您建议关闭内核的形状是什么?
  • 我使用了一个八边形,它是一个简单的近似圆。
  • 我得到了类似的结果,但不如你的好。你能告诉我你用什么大小和多少次迭代来变形。如果你还记得就关门了吗?
  • @aizuon:对不起,我不记得了。我增加直到“洞”消失。
猜你喜欢
  • 2018-02-10
  • 1970-01-01
  • 2020-06-17
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多