我使用Grabcut算法实现了背景减法。但是我在源图像的裁剪图像中有一些不需要的空白区域。如何删除裁剪图像的空白区域。?
步骤:
从相机中读取视频并阅读图像。我的输入图片:
应用Grabcut算法。
CV :: grabCut(图像,
结果,
rectangle1,
bgModel,fgModel,
1,CV :: GC_INIT_WITH_RECT);
CV ::比较(结果,CV :: GC_PR_FGD,结果,CV :: CMP_EQ);
从源中裁剪前景图像。
cv :: Mat foreground(image.size(),CV_8UC3,cv :: Scalar(255,255,255)); image.copyTo(前景,结果);
我的输出图片:
如何从图像中删除脸部区域的白色空格?
答案 0 :(得分:3)
我能想到这三种解决方案。这些中的每一个都应该应用于结果提取区域(即使用Grabcut算法后得出的区域):
对于位于提取区域边界的每个像素:
占据此像素的近邻,该像素也属于您提取的对象的边界。
将直线 A行设置为属于此邻域的像素(openCV具有执行该功能的功能:fitline())
计算与拟合线垂直的 B行。
移除/着色位于 B行上的像素,属于使用Grabcut算法提取的区域。
如果在您的应用程序中,用户可以手动应用此操作,例如通过单击图像并选择一些选项,上面给出的算法在此阶段解决了问题 - 用户可以根据需要多次执行此操作,从 B行中删除一些固定的,硬编码的像素数每次执行操作或提供每次调用操作时应删除的像素数。
如果要执行而没有任何用户交互,另一个问题是确定应删除 B行上的像素数。此问题的解决方案取决于您要处理的图像的相似程度以及背景是否均匀或颜色渐变可能有很大差异。你可以,例如比较位于边框上的像素值与背景的平均像素值(或背景的一部分,如果背景不是均匀的颜色) - 如果它们 足够相似 (您必须弄明白, 足够类似 适用于您的特定应用),该像素已移除。
迭代边界像素并将它们的值与背景像素值进行比较(解决方案1 中的详细信息)。如果像素的值 足够相似 (请参阅:解决方案1 )到背景值,请删除像素。
每次用户应用此操作时,只会移除边框像素而不会检查其值。该操作的深度(即,接近边缘的像素的数量被移除)可以是硬编码的或由用户指定。您可以将其视为一种图像侵蚀。
解决方案1 可能会产生更准确的结果,尤其是在用户应该手动执行此操作的情况下,而解决方案2 更容易实现并且计算复杂度更低。
解决方案3 是最简单的,但也是最不准确的,因为每次执行操作时,整个图片都会被裁剪,而不仅仅是实际需要裁剪的部分。在许多情况下,这可能几乎看不到,所以它也可能值得尝试。此外,此解决方案仅适用于用户手动执行此操作(因为算法无法确定应删除多少像素)。