为什么我的 copyTo 函数没有将蒙版复制到正确的垫子上?

Why is my copyTo function Not copying the mask to the correct Mat?

我从以下图片开始,命名为 rgbaMat4Mask.bmp:

然后我把它转换成HSV,然后inRange()找等高线,得到下面的Mat named maskedMat:

然后我继续在新创建的名为 newMatWithMask 的空白 Mat 上绘制第一个轮廓(较大的轮廓),它​​已被赋予 与第一张图片的大小相同 我从开始:

到目前为止一切顺利,但问题现在开始了。 我创建了一个新的 Mat 并给它 与第一个轮廓(较大的),然后将其背景颜色设置为 new Scalar(120, 255, 255)。然后我使用 copyTo 函数将 newMat4MaskFinished 复制到它。 但是生成的 Mat 的大小与轮廓的大小不同,其背景颜色也未设置为 new Scalar(120, 255, 255) 蓝色。

它是一张与整个蒙版大小相同的图像,背景为黑色。为什么? 我做错了什么?

public void doProcessing(View view) {
        // READING THE RGBA MAT
        Mat rgbaMat4Mask = Highgui.imread("/mnt/sdcard/DCIM/rgbaMat4Mask.bmp");

        // CONVERTING TO HSV
        Mat hsvMat4Mask = new Mat();
        Imgproc.cvtColor(rgbaMat4Mask, hsvMat4Mask, Imgproc.COLOR_BGR2HSV);
        Highgui.imwrite("/mnt/sdcard/DCIM/hsvMat4Mask.bmp", hsvMat4Mask);//check

        // CREATING A FILTER/MASK FOR RED COLORED BLOB
        Mat maskedMat = new Mat();
        Core.inRange(hsvMat4Mask, new Scalar(0, 100, 100), new Scalar(10, 255, 255), maskedMat);
        Highgui.imwrite("/mnt/sdcard/DCIM/maskedMat.bmp", maskedMat);// check

        // COPYING THE MASK TO AN EMPTY MAT
        // STEP 1:
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Imgproc.findContours(maskedMat, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);

        //STEP 2: 
        Mat newMat4Mask = new Mat(rgbaMat4Mask.rows(), rgbaMat4Mask.cols(), CvType.CV_8UC1);
        newMat4Mask.setTo(new Scalar(0));
        Imgproc.drawContours(newMat4Mask, contours, 0, new Scalar(255), -1);//TODO Using -1 instead of CV_FILLED.
        Highgui.imwrite("/mnt/sdcard/DCIM/newMatWithMask.bmp", newMat4Mask);// check


        //STEP 3
        Log.i(TAG, "HAPPY rows:"+contours.get(0).rows()+"   columns:"+contours.get(0).cols());
        Mat newMatwithMaskFinished = new Mat(contours.get(0).rows(), contours.get(0).cols(), CvType.CV_8UC3);
        newMatwithMaskFinished.setTo(new Scalar(120, 255, 255));
        rgbaMat4Mask.copyTo(newMatwithMaskFinished, newMat4Mask);
        Highgui.imwrite("/mnt/sdcard/DCIM/newMatwithMaskFinished.bmp", newMatwithMaskFinished);//check*/
    }

您的 newMatwithMaskFinished 应与 rgbaMat4MasknewMat4Mask 具有相同的大小。

Mat newMatwithMaskFinished = new Mat(rgbaMat4Mask.rows(), rgbaMat4Mask.cols(), CvType.CV_8UC3);

如果你只想有一个Mat的大圆圈,透明背景,那么你需要:

1) 创建 newMatwithMaskFinished 类型 CV_8UC4

Mat newMatwithMaskFinished = new Mat(rgbaMat4Mask.rows(), rgbaMat4Mask.cols(), CvType.CV_8UC4);

2) 设置透明背景:

newMatwithMaskFinished.setTo(new Scalar(0, 0, 0, 0));

3) 用 boundingRect.

计算你感兴趣的轮廓的边界框 box

4) 将 rgbaMat4Mask 转换为 4 个通道(除非它已经存在),使用 cvtColor(..., COLOR_BGR2BGRA),我们称其为 rgba

5) 将 rgba 复制到 newMatwithMaskFinished,使用掩码 newMat4Mask.

6) 在 box 上裁剪 newMatwithMaskFinished,使用 submat 方法