Java OpenCV Grabcut仅输出标记为GC_FGD的内容

Java OpenCV Grabcut仅输出标记为GC_FGD的内容,java,android,opencv,image-processing,computer-vision,Java,Android,Opencv,Image Processing,Computer Vision,我正在使用JavaCV版本3.4.2以及Android SDK 27。我想先用带面具的grabcut 这是我的输入图像(左)和遮罩(右): 请注意,这里我展示的是贴有衬衫的面具。遮罩实际上是全黑的,绿色标记为=GC_FGD,红色标记为=GC_BGD 结果如下:( 运行grabcut的代码: Mat mask = imageView.mask; // Create ROI Rect bounding_box = new Rect(0, 0, mask.cols(), mask.rows())

我正在使用JavaCV版本3.4.2以及Android SDK 27。我想先用带面具的grabcut

这是我的输入图像(左)和遮罩(右):

请注意,这里我展示的是贴有衬衫的面具。遮罩实际上是全黑的,绿色标记为=GC_FGD,红色标记为=GC_BGD

结果如下:(

运行grabcut的代码:

Mat mask = imageView.mask;

// Create ROI
Rect bounding_box = new Rect(0, 0, mask.cols(), mask.rows());

// extracted features for foreground & bg
Mat bgdModel = new Mat();
Mat fgdModel = new Mat();

// Get original image and convert from RGBA to RGB
Mat original_image = new Mat();
Utils.bitmapToMat(imageView.original_bitmap, original_image);
Imgproc.cvtColor(original_image, original_image, Imgproc.COLOR_RGBA2RGB);

// Do extraction
Imgproc.grabCut(original_image, mask, bounding_box, bgdModel, fgdModel,
        /*iterCount:*/1, Imgproc.GC_INIT_WITH_MASK);

Mat foreground = new Mat(original_image.size(), CvType.CV_8UC1,
        new Scalar(0, 0, 0));
Bitmap output_image = Bitmap.createBitmap(mask.cols(), mask.rows(),
        Bitmap.Config.ARGB_8888);
Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(0));

original_image.copyTo(foreground, mask);
Utils.matToBitmap(foreground, output_image);
以下是包装面具的代码(根据用户界面上选择的颜色,用威瑟尔GC_BGD或GC_FGD绘制在垫子上。绿色为fg,红色为bg):


我能够解决我的问题。实现中存在多个问题。我的输出只是所选的
GC\u FDG
行的原因是掩码中的所有其他内容都是
GC\u BGD
。我将掩码中的所有内容改为填充
GC\u PR\u BGD
,然后用
GC\u FDG注释这些部分de>和
GC\u BGD

这最终创建了一个不同的掩码,但输出仍然相同。
GrabCut
生成的掩码是由GrabCut自动生成的
GC\u FGD
I注释的,
GC\u PR\u BGD
(对我的图像的预测),我选择的是
GC\u BGD
,其他的都是
GC\u PR\u BGD

因此,我使用了
Core.compare
来生成适当的掩码。我更新的代码如下:

执行抓取切割操作

// Get masked from the drawing we made
Mat mask = imageView.mask;

// Create ROI
Rect bounding_box = new Rect(10, 10, mask.cols()-10,
        mask.rows()-10);

// Get original image and convert from RGBA to RGB
Mat original_image = new Mat();
Utils.bitmapToMat(imageView.original_bitmap, original_image);
Imgproc.cvtColor(original_image, original_image, Imgproc.COLOR_RGBA2RGB);

// Do extraction
Imgproc.grabCut(original_image, mask, bounding_box, new Mat(), new Mat(),
        NUM_ITERATIONS, Imgproc.GC_INIT_WITH_MASK);

// New mask to hold ONLY what was marked GC_PR_FGD by grabcut on our mask.
Mat probable_fgd_mask = new Mat();
Core.compare(mask, new Scalar(Imgproc.GC_PR_FGD), probable_fgd_mask, Core.CMP_EQ);

// Reusing mask variable, store into mask only what was marked as GC_FGD
// inside of mask.
Core.compare(mask, new Scalar(Imgproc.GC_FGD), mask, Core.CMP_EQ);

// Combine both masks so that we have GC_FGD + GC_PR_FGD
Core.add(probable_fgd_mask, mask, mask);

// We will store the foreground into an all-black Mat,
Mat foreground = new Mat(original_image.size(), CvType.CV_8UC1,
        new Scalar(0, 0, 0));

// Copy the original image to 'foreground', but mask it with our newly created
// mask (GC_FGD + GC_PR_FGD)
original_image.copyTo(foreground, mask);
创建遮罩的代码的唯一变化是我们如何创建垫子:

发件人:

致:


希望这能帮助其他人:)我被困在这上面一天半了

/*iterCount:**/1
似乎可疑。。。使用更多的迭代怎么样?@Miki I将其更改为10次迭代,结果是一样的。这看起来有关联。
// Get masked from the drawing we made
Mat mask = imageView.mask;

// Create ROI
Rect bounding_box = new Rect(10, 10, mask.cols()-10,
        mask.rows()-10);

// Get original image and convert from RGBA to RGB
Mat original_image = new Mat();
Utils.bitmapToMat(imageView.original_bitmap, original_image);
Imgproc.cvtColor(original_image, original_image, Imgproc.COLOR_RGBA2RGB);

// Do extraction
Imgproc.grabCut(original_image, mask, bounding_box, new Mat(), new Mat(),
        NUM_ITERATIONS, Imgproc.GC_INIT_WITH_MASK);

// New mask to hold ONLY what was marked GC_PR_FGD by grabcut on our mask.
Mat probable_fgd_mask = new Mat();
Core.compare(mask, new Scalar(Imgproc.GC_PR_FGD), probable_fgd_mask, Core.CMP_EQ);

// Reusing mask variable, store into mask only what was marked as GC_FGD
// inside of mask.
Core.compare(mask, new Scalar(Imgproc.GC_FGD), mask, Core.CMP_EQ);

// Combine both masks so that we have GC_FGD + GC_PR_FGD
Core.add(probable_fgd_mask, mask, mask);

// We will store the foreground into an all-black Mat,
Mat foreground = new Mat(original_image.size(), CvType.CV_8UC1,
        new Scalar(0, 0, 0));

// Copy the original image to 'foreground', but mask it with our newly created
// mask (GC_FGD + GC_PR_FGD)
original_image.copyTo(foreground, mask);
mask = new Mat (bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(Imgproc.GC_BGD));
mask = new Mat (bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(Imgproc.GC_PR_BGD));