首页 文章

如何在Grabcut算法中删除不需要的空格?

提问于
浏览
1

我使用Grabcut算法实现了背景减法 . 但是我在源图像的裁剪图像中有一些不需要的空白区域 . 如何删除裁剪图像的空白区域 .

脚步:

  • 从相机中读取视频并读取图像 . 我的输入图片:
    enter image description here

  • 应用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(前景,结果);

  • 我的输出图片:

enter image description here

如何从图像中删除脸部区域的白色空格?

1 回答

  • 3

    我能想到这三种解决方案 . 这些中的每一个都应该应用于结果提取区域(即使用Grabcut算法后得出的区域):

    解决方案1

    对于位于提取区域边界上的每个像素:

    • 占据此像素的近邻,该像素也属于提取对象的边界 .

    • line A 直接拟合到属于该邻域的像素(openCV具有执行此操作的功能:fitline()

    • 计算与拟合线垂直的 line B .

    • 删除/彩色位于 line B 上的像素,属于使用Grabcut算法提取的区域 .

    如果您的应用程序中的用户可以手动应用此操作,例如通过单击图像并选择一些选项,上面给出的算法在此阶段解决了问题 - 用户可以根据需要多次执行此操作,每次执行操作时沿着 B line 删除一些固定的,硬编码的像素数或提供每次调用操作时应删除的像素数 .

    如果要执行 without any user interaction ,则另一个问题是确定应移除 line B 上的像素数 . 此问题的解决方案取决于您要处理的图像的相似程度以及背景是否均匀或颜色渐变可能有很大差异 . 你可以,例如将边界上的像素值与背景的平均像素值(或背景的一部分,如果背景不是均匀的颜色)进行比较 - 如果它们是 similar enough (你必须弄明白,是什么 similar enough 对于您的特定应用程序),像素被删除 .

    解决方案2

    迭代边界像素并将它们的值与背景像素值进行比较( solution 1 中的详细信息) . 如果像素的值为 similar enough (参见: solution 1 )为背景值,则删除像素 .

    解决方案3

    每次用户应用此操作时,只会删除边框像素而不会检查其值 . 该操作的深度(即,接近边缘的像素的数量被移除)可以是硬编码的或由用户指定 . 你可以把它想象成一种 image erosion .


    Solution 1 可能会产生更准确的结果,尤其是在用户应该手动执行此操作的情况下,而 solution 2 更容易实现并且计算复杂度更低 .

    Solution 3 是最简单的,但也是最不准确的,因为每次执行操作时,整个画面都会被裁剪,而不仅仅是实际需要裁剪的部分 . 在许多情况下,这可能几乎看不到,所以它也可能值得尝试 . 此外,该解决方案仅在用户要手动执行此操作时才适用(因为算法将无法确定应移除多少像素) .

相关问题