所以我试图在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 :(得分: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转换为整数到函数实现。
您还应该检查值饱和时会发生什么。
答案 1 :(得分:2)
正如评论和@Antonio的答案中所述,你不能将0.1添加到整数。
如果您使用的是CV_8UC1矩阵,但想要使用浮点值,则应乘以255.
Mat1b A; // <-- type CV_8UC1
...
A += 0.1 * 255;
如果需要运行操作的结果,就像在这种情况下一样,那么最终会调用saturated_cast
。
这相当于@Antonio的答案,但它会产生更清晰的代码(至少对我而言)。
如果您对double
或Scalar
求和,则会使用相同的代码。将使用以下两种方式创建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;
}