【问题标题】:Get same image back after applying GrabCut Algorithm in OpenCV在 OpenCV 中应用 GrabCut 算法后获取相同的图像
【发布时间】:2018-10-09 00:53:43
【问题描述】:

我使用 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();
    }
}

【问题讨论】:

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


    【解决方案1】:

    我终于找到了解决问题的方法。这是在 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();
    

    }

    【讨论】:

    • yasir 你可以帮我回答这个问题:stackoverflow.com/questions/60978380/…?谢谢
    • 当从图库中选择图片时,应用会挂起任何解决方案?
    • @Vikas 这里是解决方案,首先将 guass blur 应用于位图,然后使用 grabcut ,, Mat tmp = new Mat(); Utils.bitmapToMat(位图, tmp); Imgproc.GaussianBlur(tmp,tmp,new org.opencv.core.Size(3,3),0,0); Utils.matToBitmap(tmp,bitmap);抓取算法(原始位图);如果您找到更好的解决方案,请发表评论。
    猜你喜欢
    • 2012-03-17
    • 1970-01-01
    • 2012-12-16
    • 2014-11-20
    • 1970-01-01
    • 2018-12-19
    • 2014-08-31
    • 2013-07-15
    • 1970-01-01
    相关资源
    最近更新 更多