将标量添加到Mat对象

时间:2015-08-04 09:05:18

标签: opencv addition mat

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

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

Matrix最初是 enter image description here

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

2 个答案:

答案 0 :(得分:2)

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

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

甚至更好:

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

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

Documentation for Opencv matrix expressions

答案 1 :(得分:2)

正如评论和@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;
}