最新版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