Выходное изображение Opencv4Android grabcut имеет другие цвета (более яркие цвета), чем входное изображение - PullRequest
0 голосов
/ 28 апреля 2018
public class Grabcut extends Activity {
ImageView iv;
Bitmap bitmap;
Canvas canvas;
Scalar color = new Scalar(255, 0, 0, 255);
Point tl, br;
int counter;
Bitmap bitmapResult, bitmapBackground;
Mat dst = new Mat();
final String pathToImage  = Environment.getExternalStorageDirectory()+"/gcut.png";
public static final String TAG = "Grabcut demo";
static {
      if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
      }
    }
@Override
public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
    setContentView(R.layout.grabcut_main);
    iv = (ImageView) this.findViewById(R.id.imageView);


    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.grabcut);
    Log.d(TAG, "bitmap: " + bitmap.getWidth() + "x" + bitmap.getHeight());


    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
    Log.d(TAG, "bitmap 8888: " + bitmap.getWidth() + "x" + bitmap.getHeight());


    //GrabCut part
    Mat img = new Mat();
    Utils.bitmapToMat(bitmap, img);
    Log.d(TAG, "img: " + img);

    int r = img.rows();
    int c = img.cols();

    Point p1 = new Point(c/5, r/5);
    Point p2 = new Point(c-c/5, r-r/8);

    Rect rect = new Rect(p1,p2);
    //Rect rect = new Rect(50,30, 100,200);
    Log.d(TAG, "rect: " + rect);

    Mat mask = new Mat();
    debugger(""+mask.type());
    mask.setTo(new Scalar(125));
    Mat fgdModel = new Mat();
    fgdModel.setTo(new Scalar(255, 255, 255));
    Mat bgdModel = new Mat();
    bgdModel.setTo(new Scalar(255, 255, 255));

    Mat imgC3 = new Mat();  
    Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB);
    Log.d(TAG, "imgC3: " + imgC3);

    Log.d(TAG, "Grabcut begins");
    Imgproc.grabCut(imgC3, mask, rect, bgdModel, fgdModel, 5, Imgproc.GC_INIT_WITH_RECT);

    Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0));


    Core.compare(mask, source, mask, Core.CMP_EQ);
    Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    img.copyTo(foreground, mask);
    Core.rectangle(img, p1, p2, color);

    Mat background = new Mat();
    try {
        background = Utils.loadResource(getApplicationContext(),
                R.drawable.wall2 );
    } catch (IOException e) {

        e.printStackTrace();
    }
    Mat tmp = new Mat();
    Imgproc.resize(background, tmp, img.size());

    background = tmp;

    Mat tempMask = new Mat(foreground.size(), CvType.CV_8UC1, new Scalar(255, 255, 255));
    Imgproc.cvtColor(foreground, tempMask, 6/* COLOR_BGR2GRAY */);
    //Imgproc.threshold(tempMask, tempMask, 254, 255, 1 /* THRESH_BINARY_INV */);

    Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0));
    dst = new Mat();
    background.setTo(vals, tempMask);
    Imgproc.resize(foreground, tmp, mask.size());
    foreground = tmp;
    Core.add(background, foreground, dst, tempMask);

    //convert to Bitmap
    Log.d(TAG, "Convert to Bitmap");
    Utils.matToBitmap(dst, bitmap);

    iv.setBackgroundResource(R.drawable.wall2);
    iv.setImageBitmap(bitmap);
    //release MAT part
    img.release();
    imgC3.release();
    mask.release();
    fgdModel.release();
    bgdModel.release();

}

public void debugger(String s){
    Log.v("","########### "+s);
}

}

Я следовал приведенному выше уроку. Но проблема в том, что полученное изображение имеет более яркие цвета, чем мое входное изображение. Почему это и как это решить? Мое входное изображение Здесь , а выходное изображение здесь . Выходное изображение на самом деле представляет собой скриншот моего приложения, где большое - входное изображение, а маленькое с черным фоном - выходное изображение.

1 Ответ

0 голосов
/ 02 июня 2018

Я наконец нашел решение своей проблемы. Вот код для захвата вырезанного фона изображения с использованием алгоритма Grabcut в opencv для Android.

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();
}
...