EnoxSoftware / OpenCVForUnity

OpenCV for Unity (Untiy Asset Plugin)
https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088
558 stars 175 forks source link

grabcut two masks #76

Open AndreAhmed opened 3 years ago

AndreAhmed commented 3 years ago

Hi, I have bought your unity assest. i would like help to create two masks same as the following c++ code.

Please help 👍

  auto create_mask_from_depth = [&](Mat& depth, int thresh, ThresholdTypes type)
    {
        threshold(depth, depth, thresh, 255, type);
        dilate(depth, depth, erode_less);
        erode(depth, depth, erode_more);
    };

        // Generate "near" mask image:
        auto near = frame_to_mat(bw_depth);
        cvtColor(near, near, COLOR_BGR2GRAY);
        // Take just values within range [180-255]
        // These will roughly correspond to near objects due to histogram equalization
        create_mask_from_depth(near, 180, THRESH_BINARY);

        // Generate "far" mask image:
        auto far = frame_to_mat(bw_depth);
        cvtColor(far, far, COLOR_BGR2GRAY);
        far.setTo(255, far == 0); // Note: 0 value does not indicate pixel near the camera, and requires special attention 
        create_mask_from_depth(far, 100, THRESH_BINARY_INV);

        // GrabCut algorithm needs a mask with every pixel marked as either:
        // BGD, FGB, PR_BGD, PR_FGB
        Mat mask;
        mask.create(near.size(), CV_8UC1); 
        mask.setTo(Scalar::all(GC_BGD)); // Set "background" as default guess
        mask.setTo(GC_PR_BGD, far == 0); // Relax this to "probably background" for pixels outside "far" region
        mask.setTo(GC_FGD, near == 255); // Set pixels within the "near" region to "foreground"

        // Run Grab-Cut algorithm:
        Mat bgModel, fgModel; 
        grabCut(color_mat, mask, Rect(), bgModel, fgModel, 1, GC_INIT_WITH_MASK);

        // Extract foreground pixels based on refined mask from the algorithm
        Mat3b foreground = Mat3b::zeros(color_mat.rows, color_mat.cols);
        color_mat.copyTo(foreground, (mask == GC_FGD) | (mask == GC_PR_FGD));
AndreAhmed commented 3 years ago

Here is my trial for one mask

  depth.copyTo(maskNear);
            depth.copyTo(maskFar);

            maskNear.convertTo(maskNear, CvType.CV_8U);
            Imgproc.cvtColor(maskNear, maskNear, Imgproc.COLOR_BGRA2BGR);

            Mat erodeElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4, 4));
            Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(6, 6));

            Imgproc.cvtColor(maskNear, maskNear, Imgproc.COLOR_BGR2GRAY);
            Imgproc.threshold(maskNear, maskNear, 0, 180, Imgproc.THRESH_BINARY);
            Imgproc.dilate(maskNear, maskNear, erodeElement);
            Imgproc.erode(maskNear, maskNear, dilateElement);

            convertToGrabCutValues(maskNear);

            Mat bgModel = new Mat();
            Mat fgModel = new Mat();

            Imgproc.grabCut(image, maskNear, new OpenCVForUnity.CoreModule.Rect(), bgModel, fgModel, 5, Imgproc.GC_INIT_WITH_MASK);

            convertToGrayScaleValues(maskNear); // back to grayscale values
            Imgproc.threshold(maskNear, maskNear, 128, 255, Imgproc.THRESH_TOZERO);

            Mat foreground = new Mat(image.size(), CvType.CV_8UC4, new Scalar(0, 0, 0));
            image.copyTo(foreground, maskNear);

            Utils.fastMatToTexture2D(image, texture);