最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。下面用for循环代替cv::resize函数来说明其详细的插值实现过程,其中部分代码摘自于cv::resize函数中的源代码。
每种插值算法的前部分代码是相同的,如下:
1
2
3
4
5
6
7
8
|
cv::Mat matSrc, matDst1, matDst2; matSrc = cv::imread( "lena.jpg" , 2 | 4 ); matDst1 = cv::Mat(cv::Size( 800 , 1000 ), matSrc. type (), cv::Scalar:: all ( 0 )); matDst2 = cv::Mat(matDst1.size(), matSrc. type (), cv::Scalar:: all ( 0 )); double scale_x = (double)matSrc.cols / matDst1.cols; double scale_y = (double)matSrc.rows / matDst1.rows; |
1、最近邻:公式,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
for ( int i = 0 ; i < matDst1.cols; + + i) { int sx = cvFloor(i * scale_x); sx = std:: min (sx, matSrc.cols - 1 ); for ( int j = 0 ; j < matDst1.rows; + + j) { int sy = cvFloor(j * scale_y); sy = std:: min (sy, matSrc.rows - 1 ); matDst1.at<cv::Vec3b>(j, i) = matSrc.at<cv::Vec3b>(sy, sx); } } cv::imwrite( "nearest_1.jpg" , matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 0 ); cv::imwrite( "nearest_2.jpg" , matDst2); |
2、双线性:由相邻的四像素(2*2)计算得出,公式,
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
|
uchar * dataDst = matDst1.data; int stepDst = matDst1.step; uchar * dataSrc = matSrc.data; int stepSrc = matSrc.step; int iWidthSrc = matSrc.cols; int iHiehgtSrc = matSrc.rows; for ( int j = 0 ; j < matDst1.rows; + + j) { float fy = ( float )((j + 0.5 ) * scale_y - 0.5 ); int sy = cvFloor(fy); fy - = sy; sy = std:: min (sy, iHiehgtSrc - 2 ); sy = std:: max ( 0 , sy); short cbufy[ 2 ]; cbufy[ 0 ] = cv::saturate_cast<short>(( 1.f - fy) * 2048 ); cbufy[ 1 ] = 2048 - cbufy[ 0 ]; for ( int i = 0 ; i < matDst1.cols; + + i) { float fx = ( float )((i + 0.5 ) * scale_x - 0.5 ); int sx = cvFloor(fx); fx - = sx; if (sx < 0 ) { fx = 0 , sx = 0 ; } if (sx > = iWidthSrc - 1 ) { fx = 0 , sx = iWidthSrc - 2 ; } short cbufx[ 2 ]; cbufx[ 0 ] = cv::saturate_cast<short>(( 1.f - fx) * 2048 ); cbufx[ 1 ] = 2048 - cbufx[ 0 ]; for ( int k = 0 ; k < matSrc.channels(); + + k) { * (dataDst + j * stepDst + 3 * i + k) = ( * (dataSrc + sy * stepSrc + 3 * sx + k) * cbufx[ 0 ] * cbufy[ 0 ] + * (dataSrc + (sy + 1 ) * stepSrc + 3 * sx + k) * cbufx[ 0 ] * cbufy[ 1 ] + * (dataSrc + sy * stepSrc + 3 * (sx + 1 ) + k) * cbufx[ 1 ] * cbufy[ 0 ] + * (dataSrc + (sy + 1 ) * stepSrc + 3 * (sx + 1 ) + k) * cbufx[ 1 ] * cbufy[ 1 ]) >> 22 ; } } } cv::imwrite( "linear_1.jpg" , matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 1 ); cv::imwrite( "linear_2.jpg" , matDst2); |
3、双三次:由相邻的4*4像素计算得出,公式类似于双线性
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
|
int iscale_x = cv::saturate_cast< int >(scale_x); int iscale_y = cv::saturate_cast< int >(scale_y); for ( int j = 0 ; j < matDst1.rows; + + j) { float fy = ( float )((j + 0.5 ) * scale_y - 0.5 ); int sy = cvFloor(fy); fy - = sy; sy = std:: min (sy, matSrc.rows - 3 ); sy = std:: max ( 1 , sy); const float A = - 0.75f ; float coeffsY[ 4 ]; coeffsY[ 0 ] = ((A * (fy + 1 ) - 5 * A) * (fy + 1 ) + 8 * A) * (fy + 1 ) - 4 * A; coeffsY[ 1 ] = ((A + 2 ) * fy - (A + 3 )) * fy * fy + 1 ; coeffsY[ 2 ] = ((A + 2 ) * ( 1 - fy) - (A + 3 )) * ( 1 - fy) * ( 1 - fy) + 1 ; coeffsY[ 3 ] = 1.f - coeffsY[ 0 ] - coeffsY[ 1 ] - coeffsY[ 2 ]; short cbufY[ 4 ]; cbufY[ 0 ] = cv::saturate_cast<short>(coeffsY[ 0 ] * 2048 ); cbufY[ 1 ] = cv::saturate_cast<short>(coeffsY[ 1 ] * 2048 ); cbufY[ 2 ] = cv::saturate_cast<short>(coeffsY[ 2 ] * 2048 ); cbufY[ 3 ] = cv::saturate_cast<short>(coeffsY[ 3 ] * 2048 ); for ( int i = 0 ; i < matDst1.cols; + + i) { float fx = ( float )((i + 0.5 ) * scale_x - 0.5 ); int sx = cvFloor(fx); fx - = sx; if (sx < 1 ) { fx = 0 , sx = 1 ; } if (sx > = matSrc.cols - 3 ) { fx = 0 , sx = matSrc.cols - 3 ; } float coeffsX[ 4 ]; coeffsX[ 0 ] = ((A * (fx + 1 ) - 5 * A) * (fx + 1 ) + 8 * A) * (fx + 1 ) - 4 * A; coeffsX[ 1 ] = ((A + 2 ) * fx - (A + 3 )) * fx * fx + 1 ; coeffsX[ 2 ] = ((A + 2 ) * ( 1 - fx) - (A + 3 )) * ( 1 - fx) * ( 1 - fx) + 1 ; coeffsX[ 3 ] = 1.f - coeffsX[ 0 ] - coeffsX[ 1 ] - coeffsX[ 2 ]; short cbufX[ 4 ]; cbufX[ 0 ] = cv::saturate_cast<short>(coeffsX[ 0 ] * 2048 ); cbufX[ 1 ] = cv::saturate_cast<short>(coeffsX[ 1 ] * 2048 ); cbufX[ 2 ] = cv::saturate_cast<short>(coeffsX[ 2 ] * 2048 ); cbufX[ 3 ] = cv::saturate_cast<short>(coeffsX[ 3 ] * 2048 ); for ( int k = 0 ; k < matSrc.channels(); + + k) { matDst1.at<cv::Vec3b>(j, i)[k] = abs ((matSrc.at<cv::Vec3b>(sy - 1 , sx - 1 )[k] * cbufX[ 0 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy, sx - 1 )[k] * cbufX[ 0 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx - 1 )[k] * cbufX[ 0 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx - 1 )[k] * cbufX[ 0 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx)[k] * cbufX[ 1 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufX[ 1 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx)[k] * cbufX[ 1 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx)[k] * cbufX[ 1 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 1 )[k] * cbufX[ 2 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy, sx + 1 )[k] * cbufX[ 2 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 1 )[k] * cbufX[ 2 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 1 )[k] * cbufX[ 2 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 2 )[k] * cbufX[ 3 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy, sx + 2 )[k] * cbufX[ 3 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 2 )[k] * cbufX[ 3 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 2 )[k] * cbufX[ 3 ] * cbufY[ 3 ] ) >> 22 ); } } } cv::imwrite( "cubic_1.jpg" , matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 2 ); cv::imwrite( "cubic_2.jpg" , matDst2); |
4、基于像素区域关系:共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现。
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#ifdef _MSC_VER cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 3 ); cv::imwrite( "E:/GitCode/OpenCV_Test/test_images/area_2.jpg" , matDst2); #else cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 3 ); cv::imwrite( "area_2.jpg" , matDst2); #endif fprintf(stdout, "==== start area ====\n" ); double inv_scale_x = 1. / scale_x; double inv_scale_y = 1. / scale_y; int iscale_x = cv::saturate_cast< int >(scale_x); int iscale_y = cv::saturate_cast< int >(scale_y); bool is_area_fast = std:: abs (scale_x - iscale_x) < DBL_EPSILON && std:: abs (scale_y - iscale_y) < DBL_EPSILON; if (scale_x > = 1 && scale_y > = 1 ) { / / zoom out if (is_area_fast) { / / integer multiples for ( int j = 0 ; j < matDst1.rows; + + j) { int sy = std:: min (cvFloor(j * scale_y), matSrc.rows - 1 ); for ( int i = 0 ; i < matDst1.cols; + + i) { int sx = std:: min (cvFloor(i * scale_x), matSrc.cols - 1 ); matDst1.at<cv::Vec3b>(j, i) = matSrc.at<cv::Vec3b>(sy, sx); } } #ifdef _MSC_VER cv::imwrite( "E:/GitCode/OpenCV_Test/test_images/area_1.jpg" , matDst1); #else cv::imwrite( "area_1.jpg" , matDst1); #endif return 0 ; } for ( int j = 0 ; j < matDst1.rows; + + j) { double fsy1 = j * scale_y; double fsy2 = fsy1 + scale_y; double cellHeight = cv:: min (scale_y, matSrc.rows - fsy1); int sy1 = cvCeil(fsy1), sy2 = cvFloor(fsy2); sy2 = std:: min (sy2, matSrc.rows - 2 ); sy1 = std:: min (sy1, sy2); float cbufy[ 2 ]; cbufy[ 0 ] = ( float )((sy1 - fsy1) / cellHeight); cbufy[ 1 ] = ( float )(std:: min (std:: min (fsy2 - sy2, 1. ), cellHeight) / cellHeight); for ( int i = 0 ; i < matDst1.cols; + + i) { double fsx1 = i * scale_x; double fsx2 = fsx1 + scale_x; double cellWidth = std:: min (scale_x, matSrc.cols - fsx1); int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2); sx2 = std:: min (sx2, matSrc.cols - 2 ); sx1 = std:: min (sx1, sx2); float cbufx[ 2 ]; cbufx[ 0 ] = ( float )((sx1 - fsx1) / cellWidth); cbufx[ 1 ] = ( float )(std:: min (std:: min (fsx2 - sx2, 1. ), cellWidth) / cellWidth); for ( int k = 0 ; k < matSrc.channels(); + + k) { matDst1.at<cv::Vec3b>(j, i)[k] = (uchar)(matSrc.at<cv::Vec3b>(sy1, sx1)[k] * cbufx[ 0 ] * cbufy[ 0 ] + matSrc.at<cv::Vec3b>(sy1 + 1 , sx1)[k] * cbufx[ 0 ] * cbufy[ 1 ] + matSrc.at<cv::Vec3b>(sy1, sx1 + 1 )[k] * cbufx[ 1 ] * cbufy[ 0 ] + matSrc.at<cv::Vec3b>(sy1 + 1 , sx1 + 1 )[k] * cbufx[ 1 ] * cbufy[ 1 ]); } } } #ifdef _MSC_VER cv::imwrite( "E:/GitCode/OpenCV_Test/test_images/area_1.jpg" , matDst1); #else cv::imwrite( "area_1.jpg" , matDst1); #endif return 0 ; } / / zoom in ,it is emulated using some variant of bilinear interpolation for ( int j = 0 ; j < matDst1.rows; + + j) { int sy = cvFloor(j * scale_y); float fy = ( float )((j + 1 ) - (sy + 1 ) * inv_scale_y); fy = fy < = 0 ? 0.f : fy - cvFloor(fy); sy = std:: min (sy, matSrc.rows - 2 ); short cbufy[ 2 ]; cbufy[ 0 ] = cv::saturate_cast<short>(( 1.f - fy) * 2048 ); cbufy[ 1 ] = 2048 - cbufy[ 0 ]; for ( int i = 0 ; i < matDst1.cols; + + i) { int sx = cvFloor(i * scale_x); float fx = ( float )((i + 1 ) - (sx + 1 ) * inv_scale_x); fx = fx < 0 ? 0.f : fx - cvFloor(fx); if (sx < 0 ) { fx = 0 , sx = 0 ; } if (sx > = matSrc.cols - 1 ) { fx = 0 , sx = matSrc.cols - 2 ; } short cbufx[ 2 ]; cbufx[ 0 ] = cv::saturate_cast<short>(( 1.f - fx) * 2048 ); cbufx[ 1 ] = 2048 - cbufx[ 0 ]; for ( int k = 0 ; k < matSrc.channels(); + + k) { matDst1.at<cv::Vec3b>(j, i)[k] = (matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufx[ 0 ] * cbufy[ 0 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx)[k] * cbufx[ 0 ] * cbufy[ 1 ] + matSrc.at<cv::Vec3b>(sy, sx + 1 )[k] * cbufx[ 1 ] * cbufy[ 0 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 1 )[k] * cbufx[ 1 ] * cbufy[ 1 ]) >> 22 ; } } } fprintf(stdout, "==== end area ====\n" ); #ifdef _MSC_VER cv::imwrite( "E:/GitCode/OpenCV_Test/test_images/area_1.jpg" , matDst1); #else cv::imwrite( "area_1.jpg" , matDst1); #endif |
注:以上基于area进行图像缩小的代码有问题,具体实现代码可以参考https://github.com/fengbingchun/OpenCV_Test/blob/master/src/fbc_cv/include/resize.hpp,用法如下:
1
2
3
|
fbc::Mat3BGR src(matSrc.rows, matSrc.cols, matSrc.data); fbc::Mat3BGR dst(matDst1.rows, matDst1.cols, matDst1.data); fbc::resize(src, dst, 3 ); |
5、兰索斯插值:由相邻的8*8像素计算得出,公式类似于双线性
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
int iscale_x = cv::saturate_cast< int >(scale_x); int iscale_y = cv::saturate_cast< int >(scale_y); for ( int j = 0 ; j < matDst1.rows; + + j) { float fy = ( float )((j + 0.5 ) * scale_y - 0.5 ); int sy = cvFloor(fy); fy - = sy; sy = std:: min (sy, matSrc.rows - 5 ); sy = std:: max ( 3 , sy); const double s45 = 0.70710678118654752440084436210485 ; const double cs[][ 2 ] = {{ 1 , 0 }, { - s45, - s45}, { 0 , 1 }, {s45, - s45}, { - 1 , 0 }, {s45, s45}, { 0 , - 1 }, { - s45, s45}}; float coeffsY[ 8 ]; if (fy < FLT_EPSILON) { for ( int t = 0 ; t < 8 ; t + + ) coeffsY[t] = 0 ; coeffsY[ 3 ] = 1 ; } else { float sum = 0 ; double y0 = - (fy + 3 ) * CV_PI * 0.25 , s0 = sin(y0), c0 = cos(y0); for ( int t = 0 ; t < 8 ; + + t) { double dy = - (fy + 3 - t) * CV_PI * 0.25 ; coeffsY[t] = ( float )((cs[t][ 0 ] * s0 + cs[t][ 1 ] * c0) / (dy * dy)); sum + = coeffsY[t]; } sum = 1.f / sum ; for ( int t = 0 ; t < 8 ; + + t) coeffsY[t] * = sum ; } short cbufY[ 8 ]; cbufY[ 0 ] = cv::saturate_cast<short>(coeffsY[ 0 ] * 2048 ); cbufY[ 1 ] = cv::saturate_cast<short>(coeffsY[ 1 ] * 2048 ); cbufY[ 2 ] = cv::saturate_cast<short>(coeffsY[ 2 ] * 2048 ); cbufY[ 3 ] = cv::saturate_cast<short>(coeffsY[ 3 ] * 2048 ); cbufY[ 4 ] = cv::saturate_cast<short>(coeffsY[ 4 ] * 2048 ); cbufY[ 5 ] = cv::saturate_cast<short>(coeffsY[ 5 ] * 2048 ); cbufY[ 6 ] = cv::saturate_cast<short>(coeffsY[ 6 ] * 2048 ); cbufY[ 7 ] = cv::saturate_cast<short>(coeffsY[ 7 ] * 2048 ); for ( int i = 0 ; i < matDst1.cols; + + i) { float fx = ( float )((i + 0.5 ) * scale_x - 0.5 ); int sx = cvFloor(fx); fx - = sx; if (sx < 3 ) { fx = 0 , sx = 3 ; } if (sx > = matSrc.cols - 5 ) { fx = 0 , sx = matSrc.cols - 5 ; } float coeffsX[ 8 ]; if (fx < FLT_EPSILON) { for ( int t = 0 ; t < 8 ; t + + ) coeffsX[t] = 0 ; coeffsX[ 3 ] = 1 ; } else { float sum = 0 ; double x0 = - (fx + 3 ) * CV_PI * 0.25 , s0 = sin(x0), c0 = cos(x0); for ( int t = 0 ; t < 8 ; + + t) { double dx = - (fx + 3 - t) * CV_PI * 0.25 ; coeffsX[t] = ( float )((cs[t][ 0 ] * s0 + cs[t][ 1 ] * c0) / (dx * dx)); sum + = coeffsX[t]; } sum = 1.f / sum ; for ( int t = 0 ; t < 8 ; + + t) coeffsX[t] * = sum ; } short cbufX[ 8 ]; cbufX[ 0 ] = cv::saturate_cast<short>(coeffsX[ 0 ] * 2048 ); cbufX[ 1 ] = cv::saturate_cast<short>(coeffsX[ 1 ] * 2048 ); cbufX[ 2 ] = cv::saturate_cast<short>(coeffsX[ 2 ] * 2048 ); cbufX[ 3 ] = cv::saturate_cast<short>(coeffsX[ 3 ] * 2048 ); cbufX[ 4 ] = cv::saturate_cast<short>(coeffsX[ 4 ] * 2048 ); cbufX[ 5 ] = cv::saturate_cast<short>(coeffsX[ 5 ] * 2048 ); cbufX[ 6 ] = cv::saturate_cast<short>(coeffsX[ 6 ] * 2048 ); cbufX[ 7 ] = cv::saturate_cast<short>(coeffsX[ 7 ] * 2048 ); for ( int k = 0 ; k < matSrc.channels(); + + k) { matDst1.at<cv::Vec3b>(j, i)[k] = abs ((matSrc.at<cv::Vec3b>(sy - 3 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx - 3 )[k] * cbufX[ 0 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx - 2 )[k] * cbufX[ 1 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx - 1 )[k] * cbufX[ 2 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx)[k] * cbufX[ 3 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx)[k] * cbufX[ 3 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx)[k] * cbufX[ 3 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufX[ 3 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx)[k] * cbufX[ 3 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx)[k] * cbufX[ 3 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx)[k] * cbufX[ 3 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx)[k] * cbufX[ 3 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx + 1 )[k] * cbufX[ 4 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx + 2 )[k] * cbufX[ 5 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx + 3 )[k] * cbufX[ 6 ] * cbufY[ 7 ] + matSrc.at<cv::Vec3b>(sy - 3 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 0 ] + matSrc.at<cv::Vec3b>(sy - 2 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 1 ] + matSrc.at<cv::Vec3b>(sy - 1 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 2 ] + matSrc.at<cv::Vec3b>(sy, sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 3 ] + matSrc.at<cv::Vec3b>(sy + 1 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 4 ] + matSrc.at<cv::Vec3b>(sy + 2 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 5 ] + matSrc.at<cv::Vec3b>(sy + 3 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 6 ] + matSrc.at<cv::Vec3b>(sy + 4 , sx + 4 )[k] * cbufX[ 7 ] * cbufY[ 7 ] ) >> 22 ); / / 4194304 } } } cv::imwrite( "Lanczos_1.jpg" , matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0 , 0 , 4 ); cv::imwrite( "Lanczos_2.jpg" , matDst2); |
以上代码的实现结果与cv::resize函数相同,但是执行效率非常低,只是为了详细说明插值过程。OpenCV中默认采用C++ Concurrency进行优化加速,你也可以采用TBB、OpenMP等进行优化加速。
GitHub:https://github.com/fengbingchun/OpenCV_Test/blob/master/demo/OpenCV_Test/test_opencv_funset.cpp
到此这篇关于OpenCV中resize函数插值算法的实现过程(五种)的文章就介绍到这了,更多相关OpenCV resize插值内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/fengbingchun/article/details/17335477