Java OpenCV Grabcut仅输出标记为GC_FGD的内容
我正在使用JavaCV版本3.4.2以及Android SDK 27。我想先用带面具的grabcut 这是我的输入图像(左)和遮罩(右): 请注意,这里我展示的是贴有衬衫的面具。遮罩实际上是全黑的,绿色标记为=GC_FGD,红色标记为=GC_BGD 结果如下:( 运行grabcut的代码: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())
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));