OpenCV4入门系列教程16:像素算术操作

索引地址:系列教程索引地址

上一篇:OpenCV4入门系列教程15:像素读写

像素算术操作就是基本的加减乘除。

首先,新建一个Mat对象用于操作:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){
Mat src = Mat(3,3,CV_8UC1);
cout<<src<<endl;
}

输出为:

1
2
3
4
$ ./alt
[ 0, 0, 0;
0, 0, 0;
0, 0, 0]

内部数据默认全部为0,也就是全黑。

接下来试一试基本的算术操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){
Mat src = Mat(3,3,CV_8UC1);
cout<<src<<endl;

int nCol = src.cols;//列数
int nRow = src.rows;//行数

for(int i=0;i<nRow;i++){
for(int j=0;j<nCol;j++){
src.at<uchar>(i,j)+=3;
}
}

cout<<src<<endl;

for(int i=0;i<nRow;i++){
for(int j=0;j<nCol;j++){
src.at<uchar>(i,j)-=2;
}
}

cout<<src<<endl;

for(int i=0;i<nRow;i++){
for(int j=0;j<nCol;j++){
src.at<uchar>(i,j)*=2;
}
}

cout<<src<<endl;

for(int i=0;i<nRow;i++){
for(int j=0;j<nCol;j++){
src.at<uchar>(i,j)/=3;
}
}

cout<<src<<endl;

return 0;
}

输出结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ./alt        
[ 0, 0, 0;
0, 0, 0;
0, 0, 0]
[ 3, 3, 3;
3, 3, 3;
3, 3, 3]
[ 1, 1, 1;
1, 1, 1;
1, 1, 1]
[ 2, 2, 2;
2, 2, 2;
2, 2, 2]
[ 0, 0, 0;
0, 0, 0;
0, 0, 0]

和普通的算术类似,只不过因为源Mat是8UC1类型,那么带有小数会被截断为整数。

在介绍imwrite()时,我们有直接操作像素的代码,现在我们来分析一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <vector>
#include <stdio.h>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

//--------------------------------【createAlphaMat( )函数】--------------------------------
// 描述:创建带alpha通道的Mat
//-------------------------------------------------------------------------------------------------
void createAlphaMat(Mat &mat)
{
for(int i = 0; i < mat.rows; ++i) {
for(int j = 0; j < mat.cols; ++j) {
Vec4b &rgba = mat.at<Vec4b>(i, j);//四通道数据rgba
rgba[0]= UCHAR_MAX;
rgba[1]= saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) *UCHAR_MAX);
rgba[2]= saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) *UCHAR_MAX);
rgba[3]= saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
}

int main( )
{
//创建四通道带alpha通道的Mat
Mat mat(480, 640, CV_8UC4);
createAlphaMat(mat);//写入各通道的数据

vector<int>compression_params;//设置保存参数
compression_params.push_back(IMWRITE_PNG_COMPRESSION);//使用PNG格式压缩图片
compression_params.push_back(9);

//显示图片
imwrite("透明Alpha值图.png", mat, compression_params);//设置压缩参数
imshow("生成的png图",mat);
waitKey(0);

return 0;
}

saturate_cast是OpenCV中使用的防止溢出的操作,类似于:

1
2
3
4
if(data<0)
data=0;
else if(data>255)
data=255;

然后对每个像素的每一个通道进行赋值,赋值的值由简单的算法计算得出。

下一篇:OpenCV4入门系列教程17:像素逻辑操作