双线性插值与双三次插值算法代码
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_
自由软件开发者。承接图像处理,视频智能算法,GIS,三维仿真等方面的工程项目。联系方式 QQ or wechat: 714601476。