opencv-005-像素算术操作

知识点

像素算术操作

  • 加add、减subtract、乘multiply、除divide
  • saturate_cast<T>(value) # 类型转换
    注意点:图像的数据类型、通道数目、大小必须相同

代码(c++,python)

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

/*
* 图像像素的加减乘除,两张图像大小类型要完全相同
*/
int main(){
Mat src1 = imread("../images/opencv_images/LinuxLogo.jpg");
Mat src2 = imread("../images/opencv_images/WindowsLogo.jpg");
if(src1.empty() || src2.empty()){
cout<<"conld not read image..."<<endl;
return -1;
}
imshow("input1", src1);
imshow("input2", src2);

// 加法
Mat add_result = Mat::zeros(src1.size(),src1.type());
add(src1, src2, add_result);
imshow("add_result", add_result);

// 带权重的加法,一般推荐使用这个
Mat add_weight_result = Mat::zeros(src1.size(),src1.type());
addWeighted(src1, 0.5, src2, (1.0 - 0.5), 0.0, add_weight_result);
imshow("add_weight_result", add_weight_result);

// 减法
Mat sub_result = Mat::zeros(src1.size(),src1.type());
subtract(src1, src2, sub_result);
imshow("sub_result", sub_result);

// 乘法
Mat mul_result = Mat::zeros(src1.size(),src1.type());
multiply(src1, src2, mul_result);
imshow("mul_result", mul_result);

// 除法
Mat div_result = Mat::zeros(src1.size(),src1.type());
divide(src1, src2, div_result);
imshow("div_result", div_result);

// 自己实现加法操作
int b1 = 0, g1 = 0, r1 = 0;
int b2 = 0, g2 = 0, r2 = 0;
int b = 0, g = 0, r = 0;

Mat my_add_result = Mat::zeros(src1.size(), src1.type());
for (int row = 0; row < src1.rows; ++row) {
for (int col = 0; col < src1.cols; ++col) {
b1 = src1.at<Vec3b>(row, col)[0];
g1 = src1.at<Vec3b>(row, col)[1];
r1 = src1.at<Vec3b>(row, col)[2];

b2 = src2.at<Vec3b>(row, col)[0];
g2 = src2.at<Vec3b>(row, col)[1];
r2 = src2.at<Vec3b>(row, col)[2];

// b1:0~255,b2:0~255, b1+b2可能大于255,所以需要转换,通过saturate_cast<uchar>()
my_add_result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
my_add_result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);
my_add_result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
}
}
imshow("my_add_result", my_add_result);

waitKey(0);
return 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
import cv2 as cv
import numpy as np

src1 = cv.imread("../images/opencv_images/LinuxLogo.jpg");
src2 = cv.imread("../images/opencv_images/WindowsLogo.jpg");
cv.imshow("input1", src1)
cv.imshow("input2", src2)
h, w, ch = src1.shape
print("h , w, ch", h, w, ch)

add_result = np.zeros(src1.shape, src1.dtype);
cv.add(src1, src2, add_result);
cv.imshow("add_result", add_result);

sub_result = np.zeros(src1.shape, src1.dtype);
cv.subtract(src1, src2, sub_result);
cv.imshow("sub_result", sub_result);

mul_result = np.zeros(src1.shape, src1.dtype);
cv.multiply(src1, src2, mul_result);
cv.imshow("mul_result", mul_result);

div_result = np.zeros(src1.shape, src1.dtype);
cv.divide(src1, src2, div_result);
cv.imshow("div_result", div_result);

cv.waitKey(0)
cv.destroyAllWindows()

结果

代码地址

github