将标量添加到 Mat 对象

Adding a scalar to a Mat object

所以我试图将标量值添加到 openCV 中 Mat 对象的所有元素,但是对于 raw_t_ubit8 和 raw_t_ubit16 类型,我得到了错误的结果。这是代码。

Mat A;
//Initialize Mat A; 
A = A + 0.1; 

矩阵最初是

相加的结果是完全相同的矩阵。当我尝试将标量添加到 raw_t_real 类型的矩阵时,不会出现此问题。 raw_t_ubit8 我的意思是深度是 CV_8UC1

如果正如您在评论中提到的那样,包含的值在矩阵中缩放以适合整数域 0..255,那么您还应该缩放您求和的标量值。即:

A = A + cv::Scalar(round(0.1 * 255) ); 

甚至更好:

A += cv::Scalar(round(0.1 * 255) ); 

请注意,正如 Miki 在评论中指出的那样,cv::Scalar 在任何情况下都是由 double 构成的(它是 cv::Scalar_<double>)。 可以省略舍入,但是您可以选择如何将双精度转换为整数的选择权留给函数实现。 您还应该检查值饱和时会发生什么。

Documentation for Opencv matrix expressions.

如评论和@Antonio 的回答所述,您不能将 0.1 添加到整数。

如果您正在使用 CV_8UC1 矩阵,但您想要使用浮点值,则应乘以 255。

Mat1b A; // <-- type CV_8UC1
...
A += 0.1 * 255;

如果需要转换操作结果,如本例,则最终会调用 saturated_cast

这等同于@Antonio 的回答,但它会产生更清晰的代码(至少对我而言)。 如果您对 doubleScalar 求和,将使用相同的代码。 Scalar 对象将以两种方式创建,使用:

template<typename _Tp> inline
Scalar_<_Tp>::Scalar_(_Tp v0)
{
    this->val[0] = v0;
    this->val[1] = this->val[2] = this->val[3] = 0;
}

但是,如果您需要对矩阵精确求和 0.1(而不是按 255 缩放),则需要将矩阵转换为 CV_32FC1:

#include <opencv2/opencv.hpp>
using namespace cv;

int main(int, char** argv)
{
    Mat1b A = (Mat1b(3,3) << 1,2,3,4,5,6,7,8,9);

    Mat1f F;
    A.convertTo(F, CV_32FC1);
    F += 0.1;

    return 0;
}