不同类型的 OpenCV 乘法矩阵 (cv::Mat)
OpenCV multiplying matrices (cv::Mat) of different types
错误:
what(): OpenCV(4.2.0) ../modules/core/src/arithm.cpp:691: error: (-5:Bad argument) When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified in function 'arithm_op'
代码:
// cx is a cv::Mat containing a 1280x720x1 matrix of floats
// what i want is an output of 0.0 where cx <= 0.5 and (cx-0.5)*2 otherwise
auto c0 = (cx > 0.5).mul((cx - 0.5) * 2);
我试过了:
auto c0 = (cx > 0.5).mul((cx - 0.5) * 2, CV_32F);
哪个没用。
主要问题是 (cx > 0.5)
的类型是 CV_8U
而不是 CV_32F
。
看看下面的代码示例:
//Initialize 3x3 matrix for example
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f);
//The type of "logical matrix" result of (cx > 0.5f) is UINT8 (255 where true).
cv::Mat cx_above05 = (cx > 0.5f);
为了方便起见,我使用 Image Watch 和 Visual Studio 2017。
这是 cv::Mat cx_above05 = (cx > 0.5f)
的结果:
如您所见,类型为 UINT8
,值为 255
,其中 cx>0.5
和 0
,否则为
您可以使用 convertTo 将类型转换为 CV_32F
并除以 255
:
cx_above05.convertTo(cx_above05 , CV_32F, 1.0/255.0); //Convert type to float (1.0f where true).
结果:
如您所见,类型为 FLOAT32
,255
值转到 1.0f
完整代码示例:
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f); //Initialize 3x3 matrix for example
cv::Mat cx_above05 = (cx > 0.5f); //The type of "logical matrix" result of (cx > 0.5f) is UINT8 (255 where true).
cx_above05.convertTo(cx_above05 , CV_32F, 1.0/255.0); //Convert type to float (1.0f where true).
cv::Mat c0 = cx_above05.mul((cx - 0.5f) * 2.0f);
结果:
我们可以使用 OpenCV pow
documentation:
中描述的技巧,而不是乘以掩码
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f); //Initialize 3x3 matrix for example
cv::Mat mask = (cx <= 0.5f); //The type of "logical matrix" result of (cx <= 0.5f) is UINT8 (255 where true).
cv::Mat c0 = (cx - 0.5f) * 2.0f;
cv::subtract(c0, c0, c0, mask);
我找到了一个更优雅的解决方案 (using setTo):
cv::Mat c0 = (cx - 0.5f) * 2.0f;
c0.setTo(0, cx <= 0.5f);
一行解法:
表达式((cx - 0.5f) * 2.0f)
的类型是cv::MatExpr
,我们可以将其转换为cv::Mat
:
cv::Mat c0 = ((cv::Mat)((cx - 0.5f) * 2.0f)).setTo(0, cx <= 0.5f);
错误:
what(): OpenCV(4.2.0) ../modules/core/src/arithm.cpp:691: error: (-5:Bad argument) When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified in function 'arithm_op'
代码:
// cx is a cv::Mat containing a 1280x720x1 matrix of floats
// what i want is an output of 0.0 where cx <= 0.5 and (cx-0.5)*2 otherwise
auto c0 = (cx > 0.5).mul((cx - 0.5) * 2);
我试过了:
auto c0 = (cx > 0.5).mul((cx - 0.5) * 2, CV_32F);
哪个没用。
主要问题是 (cx > 0.5)
的类型是 CV_8U
而不是 CV_32F
。
看看下面的代码示例:
//Initialize 3x3 matrix for example
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f);
//The type of "logical matrix" result of (cx > 0.5f) is UINT8 (255 where true).
cv::Mat cx_above05 = (cx > 0.5f);
为了方便起见,我使用 Image Watch 和 Visual Studio 2017。
这是 cv::Mat cx_above05 = (cx > 0.5f)
的结果:
如您所见,类型为 UINT8
,值为 255
,其中 cx>0.5
和 0
,否则为
您可以使用 convertTo 将类型转换为 CV_32F
并除以 255
:
cx_above05.convertTo(cx_above05 , CV_32F, 1.0/255.0); //Convert type to float (1.0f where true).
结果:
如您所见,类型为 FLOAT32
,255
值转到 1.0f
完整代码示例:
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f); //Initialize 3x3 matrix for example
cv::Mat cx_above05 = (cx > 0.5f); //The type of "logical matrix" result of (cx > 0.5f) is UINT8 (255 where true).
cx_above05.convertTo(cx_above05 , CV_32F, 1.0/255.0); //Convert type to float (1.0f where true).
cv::Mat c0 = cx_above05.mul((cx - 0.5f) * 2.0f);
结果:
我们可以使用 OpenCV pow
documentation:
cv::Mat cx = (cv::Mat_<float>(3, 3) << 5.0f, 0, 0, 0, 5.0f, 0, 0, 0, 5.0f); //Initialize 3x3 matrix for example
cv::Mat mask = (cx <= 0.5f); //The type of "logical matrix" result of (cx <= 0.5f) is UINT8 (255 where true).
cv::Mat c0 = (cx - 0.5f) * 2.0f;
cv::subtract(c0, c0, c0, mask);
我找到了一个更优雅的解决方案
cv::Mat c0 = (cx - 0.5f) * 2.0f;
c0.setTo(0, cx <= 0.5f);
一行解法:
表达式((cx - 0.5f) * 2.0f)
的类型是cv::MatExpr
,我们可以将其转换为cv::Mat
:
cv::Mat c0 = ((cv::Mat)((cx - 0.5f) * 2.0f)).setTo(0, cx <= 0.5f);