How to Multiply cv::Mat with mask

I'd like multiply two arrays(cv::Mat) with mask for speed up application.

In add and subtraction exists

mask - optional operation mask - 8-bit single channel array, that specifies elements of the output array to be changed

Provide OpenCV similar functionality for multiplication and divide?

I can solve it for full image and then copy data to output. But this is slow down.

cv::Mat input1(size, CV_8U|CV_16S|CV_32F);
cv::Mat input2(size, CV_8U|CV_16S|CV_32F); // or cv::Scalar
cv::Mat output(size, CV_8U|CV_16S|CV_32F);

// per pixel multiplication input1 and input2
cv::multiply(input1, input2, output);
//cv::multiply(input1, input2, output, mask);

way around for same result:

cv::Mat multiplyFull;
cv::multiply(input1, input2, multiplyFull);

// clear data in output

// set in output only multiplication given by mask
edit retag close merge delete

I don't think it's possible without copying images.

1

IMHO would be nice if you ask your question like : here is my code to do ...... is there anyway to speed up my code. then maybe i learned something from your code

Hi did you solve this problem, I have the same question about multiplying mat using mask. Thanks!

Sort by » oldest newest most voted

You can try :

multiply(x, y, z);

or you can try this :

template<typename Type>
class ParallelMultiplyWithMask : public ParallelLoopBody
{
private:
Mat &imgSrc1;
Mat &imgSrc2;
Mat &dst;

public:
ParallelMultiplyWithMask<Type>(Mat& img1,Mat &img2, Mat &d, Mat &m) :
imgSrc1(img1),
imgSrc2(img2),
dst(d),
{}
virtual void operator()(const Range& range) const CV_OVERRIDE
{

for (int y = range.start; y < range.end; y++)
{
uchar *m = mask.ptr<uchar>(y);
Type *vDst = dst.ptr<Type>(y);
Type *vSrc1 = imgSrc1.ptr<Type>(y);
Type *vSrc2 = imgSrc2.ptr<Type>(y);
for (int x = 0; x < imgSrc1.cols; x++, vDst++, vSrc1++, vSrc2++, m++)
{
if (*m)
*vDst = *vSrc1 * *vSrc2;
else
*vDst = *vSrc1;
}

}
}
};

void multiplywithMask(InputArray _src1, InputArray _src2,  OutputArray _dst, InputArray _mask)
{
CV_Assert(_src1.sameSize(_src2) && _src1.type() == _src2.type());
Mat dst(_src1.size(), _src1.type());
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
if (_src1.type() == CV_8UC1)
{
parallel_for_(Range(0, src1.rows), product);
}
else if (_src1.type() == CV_32FC1)

{
parallel_for_(Range(0, src1.rows), product);
}
dst.copyTo(_dst);

}

more