为啥我的 copyTo 函数没有将掩码复制到正确的 Mat 上?
Posted
技术标签:
【中文标题】为啥我的 copyTo 函数没有将掩码复制到正确的 Mat 上?【英文标题】:Why is my copyTo function Not copying the mask to the correct Mat?为什么我的 copyTo 函数没有将掩码复制到正确的 Mat 上? 【发布时间】:2016-01-13 16:26:53 【问题描述】:我从以下图片开始,命名为rgbaMat4Mask.bmp
:
然后我把它转成HSV,然后用inRange()
找轮廓,得到下面的Mat
命名为maskedMat
:
然后我继续在一个名为newMatWithMask
的新创建的空Mat
上绘制第一个轮廓(较大的轮廓),它的大小与第一张图像的大小相同 我从开始:
到目前为止一切顺利,但问题现在开始了。我创建了一个新的Mat
并赋予它与第一个轮廓(较大的轮廓)相同的大小 strong>,然后将其背景颜色设置为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*/
【问题讨论】:
【参考方案1】:您的newMatwithMaskFinished
的大小应与rgbaMat4Mask
和newMat4Mask
相同。
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
方法
【讨论】:
哦。所有这一切背后的目标是只拥有一个更大的红色圆圈的垫子。我所追求的最终效果是裁剪rgbaMat
,这样就只剩下较大的红色斑点,而其他所有东西(即背景和较小的红色斑点)都被丢弃了。这不可能吗?
“如果你只想拥有一个更大圆圈的垫子,带有自定义背景..” - 我需要带有 no 背景的更大圆圈。我只需要更大的圆圈
那么,透明背景?
是的,透明背景就可以了
关于你的更新,说我做Rect contourROI = Imgproc.boundingRect(contours.get(0)); Mat detectedBlobRectangle = newMatwithMaskFinished.submat(contourROI);
,我会得到一个矩形。它的背景仍然是黑色的。以上是关于为啥我的 copyTo 函数没有将掩码复制到正确的 Mat 上?的主要内容,如果未能解决你的问题,请参考以下文章