示例代码如下:
void demo::yunsuan_demo(Mat& image)
{
Mat dsc;
dsc = Mat::zeros(image.size(), image.type());
//dsc = image / Scalar(2, 2, 2);
Mat m = Mat::zeros(image.size(), image.type());
m = Scalar(20, 20, 20);
//multiply(image, m, dsc);
int w = image.cols;//列数
int h = image.rows;//行数
//int dims = image.channels();
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
Vec3b g = image.at<Vec3b>(i, j);
Vec3b he = m.at<Vec3b>(i, j);
dsc.at<Vec3b>(i, j)[0]= saturate_cast<uchar>(g[0] + he[0]);
dsc.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(g[1] + he[1]);
dsc.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(g[2] + he[2]);
}
}
imshow("运算操作", dsc);
}
在opencv里面呢,除了乘法,其它的三种算术运算都可以用我们的算数符号来进行。
Mat dsc;
dsc = image / Scalar(2, 2, 2);//除法
dsc = image + Scalar(2, 2, 2);//加法
dsc = image - Scalar(2, 2, 2);//减法
除了直接用算数符号表示,opencv还有专门的函数来完成这些运算:
Mat dsc;
Mat m = Mat::zeros(image.size(), image.type());//必须要有这句,才能用Scalar给Mat变量赋值
m = Scalar(20, 20, 20);
multiply(image, m, dsc);//乘法
divide(image,m,dsc);//除法,等价于dsc=image/m
add(image,m,dsc);//加法,同理
subtract(image,m,dsc);//减法
一些结果:
进行乘法操作后,图像亮度得到显著提高。
那么opencv是如何完成这些操作的呢,后面的for循环或许可以给我们一些启发。
1.saturate_cast<uchar>(g[0] + he[0])
saturate_cast<uchar>(),相当于C++或者C语言里面的强制类型转换,将后面数据的范围限定在0~255,大于255的数等于255,小于0的数等于0。
2.Vec3b代表了一个三位的列表,但里面的数据类型可能是不确定的,所以为了不出错,保证等式两端的数据类型相同,我们在定义dsc的时候就需要把它的大小确定,即
dsc = Mat::zeros(image.size(), image.type());
over!!!