OpenCV docs说A.mul(B)
是每元素乘法。然而,以下代码生成以下输出,然后给出此错误:
OpenCV Error: Sizes of input arguments do not match
cout << laplacian_pyramids[i][numLevels - 1 - l].rows << endl;
cout << gaussian_weight_pyramids[i][l].rows << endl;
cout << laplacian_pyramids[i][numLevels - 1 - l].cols << endl;
cout << gaussian_weight_pyramids[i][l].cols << endl;
给出:
339
339
571
571
然后:
Mat prod = gaussian_weight_pyramids[i][l].mul(laplacian_pyramids[i][numLevels - 1 - l]);
给出错误。我尝试了Mat::multiply
类似的效果。
答案 0 :(得分:6)
我建议将单个频道转换为三个频道:
Mat A = Mat::zeros(100, 200, CV_32FC1);
Mat B = Mat::zeros(100, 200, CV_32FC3);
// Mat C = A.mul(B); // Sizes of input arguments do not match
Mat Afc3;
Mat t[] = {A, A, A};
merge(t, 3, Afc3);
Mat C = Afc3.mul(B); // now Afc3 has 3 channels ans it is type of 32_FC3
// we can multiply each elem in B by the same coef from A
但是如果B是CV_8UC3类型,它不起作用,因为opencv不允许乘法具有不同类型像素的Mats。在这种情况下,将8UC3转换为32FC3记录以将每个像素缩放1 / 255.0因为32FC3中的每个像素的值都在0.0到1.0之间(当然,8UC3中的每个像素的值都在0到255之间)。
Mat A = Mat::zeros(100, 200, CV_32FC1);
Mat B = Mat::zeros(100, 200, CV_8UC3);
// Mat C = A.mul(B);
Mat Afc3, Bfc3;
Mat t[] = {A, A, A};
merge(t, 3, Afc3);
B.convertTo(Bfc3, CV_32FC3, 1/255.0);
Mat C = Afc3.mul(Bfc3);
答案 1 :(得分:3)
这种错误可能有两个原因:不同的通道数或不同类型的数据(例如,如果第一个矩阵包含unsigned char,第二个矩阵包含unsigned short)。当然可能有两个原因。通常有3种类型的解决方案可以解决您遇到的问题:
1)编写您自己的'for'循环,它将执行您需要的操作。您不会受益于OpenCV函数中可能存在的优化,但其他解决方案将有自己的开销。您可以看到有关如何以有效方式访问像素的this tutorial。
2)使用'merge'或'convertTo'之类的函数来创建相同类型和数量的通道的输入。有关代码示例,请参阅@marol发布的答案。在此解决方案中,主要开销是数据副本。这意味着额外的时间和空间。如果要对两个图像执行多个操作,这是合理的解决方案。但如果你只需要简单的乘法就不会有效。
3)使用变通办法。例如,如果您的矩阵具有相同类型但通道数不同,则可以使用reshape函数:
// two matrices of same size but different number of channels
Mat laplac(100, 200, CV_32FC3);
Mat gauss(100, 200, CV_32FC1);
// turn them into single channel matrices. they have NxM rows and 1 or 3 columns.
// note that there no copy of data. any change in them will affect original matrices
Mat laplac2 = laplac.reshape( 1, laplac.rows*laplac.cols );
Mat gauss2 = gauss.reshape( 1, gauss.rows*gauss.cols ;
// perform multiplication
laplac2.col(0) = laplac2.col(0).mul(gauss2);
laplac2.col(1) = laplac2.col(1).mul(gauss2);
laplac2.col(2) = laplac2.col(2).mul(gauss2);
这样,您只使用OpenCV内置函数而无需复制开销。但我怀疑这将比解决方案1更快,因为解决方案-1在内存访问方面更有效。
在任何情况下,你都不会有一个很好的清洁操作,只需要一行:(