1 #include "opencv2/flann.hpp"
2 #include "opencv2/opencv_modules.hpp"
3 #include "opencv2/stitching/detail/matchers.hpp"
4 #include "opencv2/imgcodecs/imgcodecs.hpp"
5 #include "opencv2/highgui.hpp"
6 #include <stdlib.h>
7 #include <math.h>
8 #include <vector>
9 using namespace cv;
10
11
12
13 #define INVALDE_DEM_VALUE -9999999
14
15 /**
16 * @brief 雙線性插值
17 *
18 * @param x 插值點列坐标
19 * @param y 插值點行坐标
20 * @param pdfValue 影像資料
21 * @param nWidth 影像資料寬度
22 * @param nHeight 影像資料高度
23 */
24 double ResampleBilinear(double x, double y, double * pdfValue, int nWidth, int nHeight)
25 {
26 double dfBilinearValue;
27 //雙線性插值計算
28 int x_floor = x;
29 int x_ceil = (x+1);
30 int y_floor = y;
31 int y_ceil = (y+1);
32
33 /*we do not handle the border, attention*/
34 if(x<0 || y<0 || (y+1) > (nHeight-1) || (x+1) > (nWidth-1) )
35 return INVALDE_DEM_VALUE;
36
37 double r1 = (x_ceil - x)*pdfValue[y_ceil*nWidth+x_floor]
38 + (x- x_floor)*pdfValue[y_ceil*nWidth+x_ceil];
39
40 double r2 = (x_ceil - x)*pdfValue[y_floor*nWidth+x_floor]
41 + (x- x_floor)*pdfValue[y_floor*nWidth+x_ceil];
42
43 dfBilinearValue = (y-y_floor)*r1 + (y_ceil - y)*r2;
44
45 return dfBilinearValue; // 所有波段都是無效值才傳回false
46 }
47
48
49 double cubic_coeff(double x){
50 x = (x>0)? x : -x;
51 if (x<1){
52 return 1-2*x*x+x*x*x;
53 }else if(x<2){
54 return 4-8*x+5*x*x-x*x*x;
55 }
56 return 0;
57 }
58
59 /**
60 * @brief 三次卷積
61 *
62 * @param x 插值點列坐标
63 * @param y 插值點行坐标
64 * @param pdfValue 影像資料
65 * @param nWidth 影像資料寬度
66 * @param nHeight 影像資料高度
67 */
68 double ResampleCubic(double x, double y, double * pdfValue, int nWidth, int nHeight)
69 {
70 double dfCubicValue;
71 int i = x;
72 int j = y;
73
74 /*we do not handle the border, attention*/
75 if((i-1)<0 || (j-1)<0 || (j+2) > (nHeight-1) || (i+2) > (nWidth-1) )
76 return INVALDE_DEM_VALUE;
77
78 /*get adjacent 16 values*/
79 double values[4][4];
80 for (int r = j-1,s=0; r <= j+2; r++,s++){
81 for (int c = i-1,t=0; c <= i+2; c++,t++){
82 values[s][t] = pdfValue[r*nWidth+c];
83 }
84 }
85
86 /*calc the coeff*/
87 double u = x - i;
88 double v = y - j;
89 double A[4],C[4];
90 for (int distance =1,s=0;distance >=-2; distance --,s++){
91 A[s] = cubic_coeff(u+distance);
92 C[s] = cubic_coeff(v+distance);
93 }
94
95 dfCubicValue = 0;
96 for (int s = 0; s < 4; s++) {
97 for (int t = 0; t < 4; t++){
98 dfCubicValue += values[s][t]*A[t]*C[s];
99 }
100 }
101 return dfCubicValue;
102 }
103
104 void main(){
105 Mat pano = cv::imread("D:/warehouse/data/test.jpg");
106 Mat gray;
107 cvtColor(pano, gray,CV_BGR2GRAY);
108 Mat gray32;
109 gray.convertTo(gray32,CV_64FC1);
110
111
112 Mat bil(gray32.rows*2, gray32.cols*2, CV_64FC1);
113 Mat cub(gray32.rows*2, gray32.cols*2, CV_64FC1);
114
115 /*copy MAT data to a buffer*/
116 int stride = gray32.step.p[0];
117 double *data = new double[gray32.cols* gray32.rows];
118 for (int i = 0; i < gray32.rows; i++){
119 char* p = ((char*)data)+i* gray32.cols*sizeof(double);
120 memcpy(p, gray32.data+stride*i, gray32.cols*sizeof(double));
121 }
122
123 /*interpolate, Bilinear*/
124 for (int r = 0; r < bil.rows; r++){
125 for (int c = 0; c < bil.cols; c++){
126 double k = r/2.0;
127 double j = c/2.0;
128 bil.at<double>(r,c) = ResampleBilinear(j, k, data, gray32.cols, gray32.rows);
129 }
130 }
131
132
133 /*interpolate, Cubic3*/
134 for (int r = 0; r < bil.rows; r++){
135 for (int c = 0; c < bil.cols; c++){
136 double k = r/2.0;
137 double j = c/2.0;
138 cub.at<double>(r,c) = ResampleCubic(j, k, data, gray32.cols, gray32.rows);
139 }
140 }
141
142 Mat bilShow;
143 bil.convertTo(bilShow,CV_8UC1);
144 namedWindow("bil",1);
145 imshow("bil",bilShow);
146 imwrite("d:/bil.jpg", bilShow);
147
148 namedWindow("pano",1);
149 imshow("pano",pano);
150 Mat cubShow;
151 cub.convertTo(cubShow,CV_8UC1);
152 namedWindow("cub",1);
153 imshow("cub",cubShow);
154 imwrite("d:/cub.jpg", cubShow);
155
156 waitKey();
157 return;
158 }
參考:http://baike.baidu.com/link?url=femZWLyq-bZ3tX887kzps3vfKspkdugWNs4k9MV4Cq7RiXtGz8gvao3Ac2Or0DE3Mf8ooIG0ZaqdgzobnL6me_