opencv实现双线性插值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/love_image_xie/article/details/87969405

双线性插值原理如下图:

编程如下:

#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坐标系如下:

猜你喜欢

转载自blog.csdn.net/love_image_xie/article/details/87969405