opencv实现双线性插值
双线性插值原理如下图:
编程如下:
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//实现双线性插值
Mat BilinearInterpolation(Mat& src)
{
CV_Assert(src.data!=NULL);
int srcRows = src.rows;
int srcCols = src.cols;
//定义目标函数
Mat dst=Mat::zeros(150,150,src.type());
int dstRows = dst.rows;
int dstCols = dst.cols;
//缩放因子
double sx = src.cols / dst.cols;
double sy = src.rows / dst.rows;
for (int i = 0; i < dst.rows; i++)
{
//求目标图像的像素对应原图像的坐标,为了使得目标图像中心与原图像中心对齐,使用下面的公式
double index_i = (i + 0.5)*sy - 0.5;
//判断是否越界
if (index_i < 0)
index_i = 0;
if (index_i > src.rows - 1)
index_i = src.rows - 1;
int i1 = cvFloor(index_i);//向下取整
int i2 = cvCeil(index_i);
double v = index_i - i1;
for (int j = 0; j < dst.cols; j++)
{
double index_j = (j + 0.5)*sx - 0.5;
if (index_j < 0)
index_j = 0;
if (index_j > src.cols - 1)
index_j = src.cols - 1;
int j1 = cvFloor(index_j);
int j2 = cvCeil(index_j);
double u = index_j - j1;
if (src.channels() == 1)
dst.at<uchar>(i, j) = cvFloor((1 - u)*(1 - v)*src.at<uchar>(i1, j1) + (1 - u)*v*src.at<uchar>(i2, j1) + u*(1 - v)*src.at<uchar>(i1, j2) + u*v*src.at<uchar>(i2, j2));
else
{
dst.at<Vec3b>(i, j)[0] = cvFloor((1 - u)*(1 - v)*src.at<Vec3b>(i1, j1)[0] + (1 - u)*v*src.at<Vec3b>(i2, j1)[0] + u*(1 - v)*src.at<Vec3b>(i1, j2)[0] + u*v*src.at<Vec3b>(i2, j2)[0]);
dst.at<Vec3b>(i, j)[1] = cvFloor((1 - u)*(1 - v)*src.at<Vec3b>(i1, j1)[1] + (1 - u)*v*src.at<Vec3b>(i2, j1)[1] + u*(1 - v)*src.at<Vec3b>(i1, j2)[1] + u*v*src.at<Vec3b>(i2, j2)[1]);
dst.at<Vec3b>(i, j)[2] = cvFloor((1 - u)*(1 - v)*src.at<Vec3b>(i1, j1)[2] + (1 - u)*v*src.at<Vec3b>(i2, j1)[2] + u*(1 - v)*src.at<Vec3b>(i1, j2)[2] + u*v*src.at<Vec3b>(i2, j2)[2]);
}
}
}
imshow("src", src);
imshow("dst", dst);
waitKey(0);
return dst;
}
int main()
{
Mat src = imread("E:\\研究生\\学习材料\\学习书籍\\OpenCV图像处理编程实例-源码-20160801\\《OpenCV图像处理编程实例-源码-20160801\\images\\flower3.jpg");
if (!src.data)
return -1;
Mat result = BilinearInterpolation(src);
}
注意dst.at<Vec3b>(i,j)表示第i行第j列,即先y再x,因为opencv坐标系如下: