我已经使用Grabcut算法实现了背景减法。但是我在源图像的裁剪图像中有一些不需要的空白。如何删除裁切图像的空白?
脚步:
从相机读取视频并读取图像。我的输入图片:
应用Grabcut算法。
cv :: grabCut(图片,
结果,
矩形1,bgModel,fgModel,1,cv :: GC_INIT_WITH_RECT); cv :: compare(结果,cv :: GC_PR_FGD,结果,cv :: CMP_EQ);
来自源的裁剪后的前景图像。
cv ::垫前景(image.size(),CV_8UC3,cv :: Scalar(255,255,255)); image.copyTo(foreground,result);
我的输出图像:
如何从图像中删除面部区域的空白?
我可以想到三种解决方案。所有这些都应应用于结果提取区域(即,使用Grabcut算法后得出的区域):
对于位于提取区域边界上的每个像素:
拍摄该像素的近邻,该像素也属于所提取对象的边界。
将直线A拟合到属于该邻域的像素(openCV具有执行此功能的函数:fitline())
计算垂直于拟合线的线B。
删除/涂色B线上属于您的区域的像素,这些像素属于用Grabcut算法提取的区域。
如果在您的应用程序中用户可以手动执行此操作(例如,通过单击图像并选择某个选项),则以上给出的算法可以在此阶段解决问题-用户可以根据需要执行此操作多次,并删除一些固定的,硬编码的每次执行该操作时沿B线的像素数,或者提供每次调用该操作时应删除的像素数。
如果要在没有任何用户交互的情况下执行该操作,则另一个问题是确定应删除沿线B的多少像素。该问题的解决方案取决于您要处理的图像的相似程度,以及背景是否均匀或颜色梯度的变化可能很大。例如,您可以将边界上的像素值与背景(或背景的一部分,如果背景不是均匀颜色)的平均像素值进行比较-如果它们足够相似(并且您必须找出,对于您的特定应用足够相似),像素将被删除。
迭代边界像素,并将其值与背景像素值进行比较(解决方案1中的详细信息)。如果像素的值与背景值足够相似(请参阅:解决方案1),请删除像素。
每次用户执行此操作时,边框像素将被删除而不会影响其值。该操作的深度(即接近要去除的边缘的像素数)可以是硬编码的,也可以由用户指定。您可以将其视为一种图像侵蚀。
解决方案1可能会产生更准确的结果,特别是在假定用户手动执行此操作的情况下,而解决方案2更易于实现且计算复杂度较低。
解决方案3是最简单的方法,也是最不准确的方法,因为每次执行该操作时,整个图片都会被裁剪,而不仅仅是实际需要裁剪的部分。在许多情况下,这可能几乎看不到,因此也值得尝试。同样,该解决方案仅在用户手动执行此操作时才适用(因为该算法将无法确定应删除多少个像素)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句