需要 Mat 数据乘以一个系数
cout << "Bgain: " << Bgain << endl;
cout << "Ggain: " << Ggain << endl;
cout << "Rgain: " << Rgain << endl;
一、 常数变同型矩阵,采用 Mat::multiply 函数 进行矩阵运算。
需要注意的2个问题:
1、如果常数是浮点型,那么定义同型矩阵时候,要定义成CV_32FC1的格式,否则会变成 取整处理后的同型矩阵;
2、采用Mat::multiply函数进行运算时,会发生报错现象,目前未解决。
Mat BgainMat(B.rows, B.cols, CV_8UC1, Scalar::all(Bgain));
Mat GgainMat(G.rows, G.cols, CV_8UC1, Scalar::all(Ggain));
Mat RgainMat(R.rows, R.cols, CV_8UC1, Scalar::all(Rgain));
Rect re(4180, 1650, 6, 6);
cout << "BgainMat: " << BgainMat(re) << endl;
cout << "GgainMat: " << GgainMat(re) << endl;
cout << "RgainMat: " << RgainMat(re) << endl;
修改Scalar 数值:
Mat BgainMat(B.rows, B.cols, CV_8UC1, Scalar::all(3.56));
Mat GgainMat(G.rows, G.cols, CV_8UC1, Scalar::all(1.25));
Mat RgainMat(R.rows, R.cols, CV_8UC1, Scalar(Rgain));
Rect re(4180, 1650, 6, 6);
cout << "BgainMat: " << BgainMat(re) << endl;
cout << "GgainMat: " << GgainMat(re) << endl;
cout << "RgainMat: " << RgainMat(re) << endl;
原因: 无论Scalar是什么浮点值,输出的均为四舍五入后的整数型
问题不在输入参数,在于Mat类型的定义 8UC1
Mat.hpp 源码 :
int type() const;
/** @brief Returns the depth of a matrix element.
The method returns the identifier of the matrix element depth (the type of each individual channel).
For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of
matrix types contains the following values:
- CV_8U - 8-bit unsigned integers ( 0..255 )
- CV_8S - 8-bit signed integers ( -128..127 )
- CV_16U - 16-bit unsigned integers ( 0..65535 )
- CV_16S - 16-bit signed integers ( -32768..32767 )
- CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
- CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
- CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
*/
矩阵输出问题解决,
但是矩阵运算出现报错
multiply(B, BgainMat, newB);
multiply(G, GgainMat, newG);
multiply(R, RgainMat, newR);
二、 通过 cvConvertScale 函数进行运算。
但是 : 存在一些小问题
cvConvertScale(B, newB, Ggain,0);
参考博文 : 上篇转载 该博文的解决方案是,针对Mat类型的数据,选用不以cv开头的函数。
cvConvertScale :以cv开头的函数 输入参数列表 矩阵类型 大都为 cv::Arr * 类型 以Mat类型作为输入参数时会报错的 不存在 Mat 到 Arr的适当转换函数
convertMaps : 不带cv的函数 输入参数多为 cv::inputArray 类型 , 此类函数 输入参数类型 Mat 类型的是可以的。
三、自己写代码,对Mat数据元素进行操作的方式实现:
需要注意存在的问题:当计算结果超出255时,注意处理溢出问题。否则图像结果会发生如下的问题。
for (int i = 0; i < B.rows;i++){
//uchar* dataB = B.ptr(i);
//uchar* dataNewB = newB.ptr(i);
for (int j = 0; j < B.cols;j++){
//dataNewB[j] = dataB[j] * Bgain; // 指针访问的方式 操作数据元素
//dataNewG[j] = dataG[j] * Ggain;
//dataNewR[j] = dataR[j] * Rgain;
newB.at(i, j) = B.at(i, j) * Bgain; // 动态地址访问方式 操作数据元素
newG.at(i, j) = G.at(i, j) * Ggain;
newR.at(i, j) = R.at(i, j) * Rgain;
}
}
处理后的图片效果:
四、简洁可行
最后,最后, 发现,Mat矩阵 直接乘以数值就可以了,并且能自动满足溢出时取最大值255的处理。 兜兜转转一大圈,最初曾经这样试过,可能某个地方出问题了,结果绕了一圈,想了很多其它的如前述的方式进行计算,足足花费一天时间。
newB = B * Bgain;
newG = G * Ggain;
newR = R * Rgain;
cout << "newB: " << newB(re) << endl;
cout << "newG: " << newG(re) << endl;
cout << "newR: " << newR(re) << endl;
cout << "newC: " << newC(re) << endl;