I am working on do a pixel-wise multiple between a 2-dimension imageA(CV_32FC1) with another 3-dimension imageB(CV_32FC3) with OpenCV, i.e. imageA pixel-wise multiply each R\G\B channel of imageB. This is same as broadcast imageA to 3-dimension along the 3-th direction, then pixel-wise with imageB. Now, I do it by:
vector<Mat> temp{imageA, imageA, imageA}; // imageA is CV_32FC1
merge(temp, sampA); // sameA is CV_32FC3 now, and each channel is same as imageA
Out = imageB.mul(sampA); // imageB is CV_32FC3, and do pixel-wise with sameA
My Question is: Can I have another more effective way to do this purpose with OpenCV? Such like a function in OpenCV.
I know this is same as "Broadcast" in MXNet, i.e. broadcast a 2-dimension image to 3-dimension image along the 3-th direction, and each channel of result is same the input 2-dimension image.
Thanks in advance :-)
Mat matmul32F(Mat& bgr, Mat& mask)
{
assert(bgr.type() == CV_32FC3 && mask.type() == CV_32FC1 && bgr.size() == mask.size());
int H = bgr.rows;
int W = bgr.cols;
Mat dst(bgr.size(), bgr.type());
if (bgr.isContinuous() && mask.isContinuous())
{
W *= H;
H = 1;
}
for( int i = 0; i < H; ++i)
{
float* pdst = ((float*)dst.data)+i*W*3;
float* pbgr = ((float*)bgr.data)+i*W*3;
float* pmask = ((float*)mask.data) + i*W;
for ( int j = 0; j < W; ++j)
{
(*pdst++) = (*pbgr++) *(*pmask);
(*pdst++) = (*pbgr++) *(*pmask);
(*pdst++) = (*pbgr++) *(*pmask);
pmask+=1;
}
}
return dst;
}
Most efficient way to is iteration by yourself.
I test three method for :
A: use
merge
andmul
B: use
cvtColor
andmul
C: loop sing pointer and mutiply by hand.
As for time costing, in most case, A ≈ B ≈ 2 x C
. A typical time costing is:
Test A: 3.23E-03 s
Test B: 3.26E-03 s
Test C: 1.85E-03 s