在OpenCV中应用GrabCut算法后获取相同的图像

时间:2018-04-28 09:21:21

标签: android opencv image-processing image-segmentation opencv4android

我使用GrabCut算法对我的图片进行细分my image 在我的图像中检测柑橘(水果)作为前景并从背景中减去它。为此目的首先我必须在我的对象(水果)周围选择2个点,用于在我的对象(水果)周围绘制矩形,然后我应用抓取算法来减去我的图像的背景。问题是我在应用抓取切割算法后得到相同的图像(没有任何对象检测背景减除)。 Bellow是我的Android(OpenCV)代码

public boolean imgProcessingButton(View view) {

            if (mCurrentPhotoPath != null)
                targetChose = false;
            mImageView.setOnTouchListener(new View.OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        if (touchCount == 0) {
                            tl.x = event.getX();
                            tl.y = event.getY();
                            touchCount++;
                        }
                        else if (touchCount == 1) {
                            br.x = event.getX();
                            br.y = event.getY();

                            Paint rectPaint = new Paint();
                            rectPaint.setARGB(255, 255, 0, 0);
                            rectPaint.setStyle(Paint.Style.STROKE);
                            rectPaint.setStrokeWidth(3);
                            Bitmap tmpBm = Bitmap.createBitmap(mBitmap.getWidth(),
                                    mBitmap.getHeight(), Bitmap.Config.RGB_565);
                            Canvas tmpCanvas = new Canvas(tmpBm);

                            tmpCanvas.drawBitmap(mBitmap, 0, 0, null);
                            tmpCanvas.drawRect(new RectF((float) tl.x, (float) tl.y, (float) br.x, (float) br.y),
                                    rectPaint);
                            mImageView.setImageDrawable(new BitmapDrawable(getResources(), tmpBm));

                            targetChose = true;
                            touchCount = 0;
                            mImageView.setOnTouchListener(null);
                        }
                    }

                    return true;
                }
            });

            return true;}
public boolean imgCutButton(View view) {
            if (mCurrentPhotoPath != null && targetChose) {
                new ProcessImageTask().execute();
                targetChose = false;
            }
            return true;
    }

private class ProcessImageTask extends AsyncTask<Integer, Integer, Integer> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dlg.setMessage("Processing Image...");
        dlg.setCancelable(false);
        dlg.setIndeterminate(true);
        dlg.show();
    }

    @Override
    protected Integer doInBackground(Integer... params) {
        Mat img = Imgcodecs.imread(mCurrentPhotoPath);
        Mat background = new Mat(img.size(), CvType.CV_8UC3,
                new Scalar(255, 255, 255));
        Mat firstMask = new Mat();
        Mat bgModel = new Mat();
        Mat fgModel = new Mat();
        Mat mask;
        Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(Imgproc.GC_PR_FGD));
        Mat dst = new Mat();
        Rect rect = new Rect(tl, br);

        Imgproc.grabCut(img, firstMask, rect, bgModel, fgModel,
                5, Imgproc.GC_INIT_WITH_RECT);
        Core.compare(firstMask, source, firstMask, Core.CMP_EQ);

        Mat foreground = new Mat(img.size(), CvType.CV_8UC3,
                new Scalar(255, 255, 255));
        img.copyTo(foreground, firstMask);

        Scalar color = new Scalar(255, 0, 0, 255);
        Imgproc.rectangle(img, tl, br, color);

        Mat tmp = new Mat();
        Imgproc.resize(background, tmp, img.size());
        background = tmp;
        mask = new Mat(foreground.size(), CvType.CV_8UC1,
                new Scalar(255, 255, 255));

        Imgproc.cvtColor(foreground, mask, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(mask, mask, 254, 255, Imgproc.THRESH_BINARY_INV);
        System.out.println();
        Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0));
        background.copyTo(dst);

        background.setTo(vals, mask);

        Core.add(background, foreground, dst, mask);

        firstMask.release();
        source.release();
        bgModel.release();
        fgModel.release();
        vals.release();

        Imgcodecs.imwrite(mCurrentPhotoPath , dst);
        //displayImage(dst);
        return 0;
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);

        Bitmap jpg = BitmapFactory
                .decodeFile(mCurrentPhotoPath );

        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        imageView.setAdjustViewBounds(true);
        imageView.setPadding(2, 2, 2, 2);
        imageView.setImageBitmap(jpg);
        imageView.invalidate();

        dlg.dismiss();
    }
}

1 个答案:

答案 0 :(得分:0)

我终于找到了解决问题的方法。下面是在opencv for android中使用Grabcut算法抓取图像背景的代码。

public void grabcutAlgo(Bitmap bit){
Bitmap b = bit.copy(Bitmap.Config.ARGB_8888, true);
Point tl=new Point();
Point br=new Point();
//GrabCut part
Mat img = new Mat();
Utils.bitmapToMat(b, img);
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGBA2RGB);

int r = img.rows();
int c = img.cols();
Point p1 = new Point(c / 100, r / 100);
Point p2 = new Point(c - c / 100, r - r / 100);
Rect rect = new Rect(p1, p2);
//Rect rect = new Rect(tl, br);
Mat background = new Mat(img.size(), CvType.CV_8UC3,
        new Scalar(255, 255, 255));
Mat firstMask = new Mat();
Mat bgModel = new Mat();
Mat fgModel = new Mat();
Mat mask;
Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(Imgproc.GC_PR_FGD));
Mat dst = new Mat();


Imgproc.grabCut(img, firstMask, rect, bgModel, fgModel, 5, Imgproc.GC_INIT_WITH_RECT);
Core.compare(firstMask, source, firstMask, Core.CMP_EQ);

Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));

img.copyTo(foreground, firstMask);

Scalar color = new Scalar(255, 0, 0, 255);
Imgproc.rectangle(img, tl, br, color);

Mat tmp = new Mat();
Imgproc.resize(background, tmp, img.size());
background = tmp;
mask = new Mat(foreground.size(), CvType.CV_8UC1,
        new Scalar(255, 255, 255));

Imgproc.cvtColor(foreground, mask, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(mask, mask, 254, 255, Imgproc.THRESH_BINARY_INV);
System.out.println();
Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0));
background.copyTo(dst);

background.setTo(vals, mask);

Core.add(background, foreground, dst, mask);
Bitmap grabCutImage = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
Bitmap processedImage = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.RGB_565);
Utils.matToBitmap(dst, grabCutImage);
dst.copyTo(sampleImage);
imageView.setImageBitmap(grabCutImage);
firstMask.release();
source.release();
bgModel.release();
fgModel.release();

}