在opencv-java中优化GrabCut的性能

May*_*ari 16 java algorithm opencv

最近我得到了一个项目,我必须从给定的图像中提取面部(面部+头发).

我通过以下方式解决这个问题.

  1. 我从给定的图像中提取面部位置.[我得到一个矩形]
  2. 我正在提取该矩形并将其放置在与输入图像相同尺寸的另一个图像中.[face_image]
  3. 我在第2步的face_image上应用了grabCut算法.

当face_image包含平滑背景时,算法会抓住它,但是当face_image的背景很复杂时,算法grabCut也会在处理过的图像中提取背景的某些部分.

这是我得到的结果的快照.

每个步骤的结果

这是我的grabCut代码:

public void extractFace(Mat image, String fileNameWithCompletePath, 
                       int xOne, int xTwo, int yOne, int yTwo) throws CvException {

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    Rect rectangle = new Rect(xOne, yOne, xTwo, yTwo);
    Mat result = new Mat();
    Mat bgdModel = new Mat();
    Mat fgdModel = new Mat();
    Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3));
    Imgproc.grabCut(image, result, rectangle, bgdModel, fgdModel, 8, Imgproc.GC_INIT_WITH_RECT);
    Core.compare(result, source, result, Core.CMP_EQ);
    Mat foreground = new Mat(image.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    image.copyTo(foreground, result);
    Imgcodecs.imwrite(fileNameWithCompletePath, foreground);
}
Run Code Online (Sandbox Code Playgroud)

如何提高grabCut算法的性能,使其仅检测给定图像的面部和头发?

Ric*_*ith 9

您应该能够通过"帮助" grabCut了解前景和背景来做到这一点.有一个python教程,通过选择前景和背景显示如何手动完成.

要自动执行此操作,您需要找到检测前景和背景的编程方法.前景主要由头发和皮肤组成,因此您需要检测它们.

皮肤 - 关于如何做到这一点,有几篇论文和博客.其中一些非常简单,这个OpenCV教程也可能有所帮助.我发现平淡的色调/饱和度让我相当远.

头发-这是棘手的,但肯定是可行的.你可能会发型,只是使用皮肤和背景,如果这是太多的工作.

背景 - 您应该可以使用range()在图像中查找紫色,绿色和蓝色的内容.你肯定知道这些东西不是皮肤或头发,因此是背景的一部分.

使用阈值创建最可能是皮肤,头发和背景的区域的蒙版.然后,您可以将它们用作bgdModelfgdModel(或皮肤和头发蒙版)而不是Mat().

对不起,这是如此高级别.我希望它有所帮助!