图像算法(一):最近邻插值,双线性插值,三次插值

最近在复习图像算法,对于一些简单的图像算法进行一个代码实现,由于找工作比较忙,具体原理后期补上,先上代码。今天先给出最近邻插值,双线性插值,三次插值。
1.最近邻插值
原始图中影响点数为1
(1)代码

# include
# include

using namespace std;
using namespace cv;

Mat NearInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows*kx);
	int cols = cvRound(srcImage.cols*ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j, x, y;
	for (i = 0; i < rows; i++)
	{
		x = static_cast((i + 1) / kx + 0.5) - 1;
		for (j = 0; j < cols; j++)
		{
			y = static_cast((j + 1) / ky + 0.5) - 1;
			resultImg.at(i, j) = srcImage.at(x, y);
		}
	}
	return resultImg;
}

int main()
{
	Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
	Mat resultImg = NearInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6,1.2", resultImg);
	waitKey(0);
	return 0;
}

(2)结果:
图像算法(一):最近邻插值,双线性插值,三次插值_第1张图片
2.线性插值
与原图中相关的点数为4
(1)代码

# include
# include

using namespace cv;

Mat LinerInter(Mat &srcImage, double kx, double ky);

int main()
{
	Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
	Mat resultImg = LinerInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6, 1.2", resultImg);
	waitKey(0);
	return 0;
}

Mat LinerInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows*kx);
	int cols = cvRound(srcImage.cols*ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j;
	int xi;
	int yi;
	int x11;
	int y11;
	double xm;
	double ym;
	double dx;
	double dy;

	for (i = 0; i < rows; i++)
	{
		xm = i / kx;
		xi = (int)xm;
		x11 = xi + 1;
		dx = xm - xi;
		for (j = 0; j < cols; j++)
		{
			ym = j / ky;
			yi = (int)ym;
			y11 = yi + 1;
			dy = ym - yi;
			//判断边界
			if (x11 >(srcImage.rows - 1))
			{
				x11 = xi - 1;
			}
			if (y11 > (srcImage.cols - 1))
			{
				y11 = yi - 1;
			}
			//bgr
			resultImg.at(i, j)[0] = (int)(srcImage.at(xi, yi)[0] * (1 - dx)*(1 - dy)
				+ srcImage.at(x11, yi)[0] * dx*(1 - dy)
				+ srcImage.at(xi, y11)[0] * (1 - dx)*dy
				+ srcImage.at(x11, y11)[0] * dx*dy);
			resultImg.at(i, j)[1] = (int)(srcImage.at(xi, yi)[1] * (1 - dx)*(1 - dy)
				+ srcImage.at(x11, yi)[1] * dx*(1 - dy)
				+ srcImage.at(xi, y11)[1] * (1 - dx)*dy
				+ srcImage.at(x11, y11)[1] * dx*dy);
			resultImg.at(i, j)[2] = (int)(srcImage.at(xi, yi)[2] * (1 - dx)*(1 - dy)
				+ srcImage.at(x11, yi)[2] * dx*(1 - dy)
				+ srcImage.at(xi, y11)[2] * (1 - dx)*dy
				+ srcImage.at(x11, y11)[2] * dx*dy);
		}

	}
	return resultImg;
}

(2)结果:
图像算法(一):最近邻插值,双线性插值,三次插值_第2张图片
3.三次插值
基于bicubic函数的权值计算,取a = -0.5
图像算法(一):最近邻插值,双线性插值,三次插值_第3张图片
与原图相关的点数为16
(1)代码

# include
# include
# include
using namespace cv;
using namespace std;

float Bicubic(float x);
Mat ThreeInter(Mat &srcImage, double kx, double ky);

int main()
{
	Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
	if (!srcImg.data)
	{
		cout << "图片不存在" << endl;
	}
	Mat resultImg = ThreeInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6,1.2", resultImg);
	waitKey(0);
	return 0;
}


float Bicubic(float y)
{
	float x = abs(y);
	float a = -0.5;
	if (x <= 1.0)
	{
		return (a + 2)*pow(x, 3) - (a + 3)*pow(x, 2) + 1;
	}
	else if (x < 2.0)
	{
		return a*pow(x, 3) + 5 * a*pow(x, 2) - 4 * a;
	}
	else
	{
		return 0.0;
	}
}

Mat ThreeInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows * kx);
	int cols = cvRound(srcImage.cols * ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j;
	int xm, ym;
	int x0, y0, xi, yi, x1, y1, x2, y2;
	float wx0, wy0, wxi, wyi, wx1, wy1, wx2, wy2;
	float w00, w01, w02, w0i, w10, w11, w12, w1i, w20, w21, w22, w2i, wi0, wi1, wi2, wii;
	for (i = 0; i < rows; i++)
	{
		xm = i / kx;
		xi = (int)xm;
		x0 = xi - 1;
		x1 = xi + 1;
		x2 = xi + 2;
		wx0 = Bicubic(x0 - xm);
		wxi = Bicubic(xi - xm);
		wx1 = Bicubic(x1 - xm);
		wx2 = Bicubic(x2 - xm);
		for (j = 0; j < cols; j++)
		{
			ym = j / ky;
			yi = (int)ym;
			y0 = yi - 1;
			y1 = yi + 1;
			y2 = yi + 2;
			wy0 = Bicubic(y0 - ym);
			wyi = Bicubic(yi - ym);
			wy1 = Bicubic(y1 - ym);
			wy2 = Bicubic(y2 - ym);
			w00 = wx0*wy0;
			w01 = wx0*wy1;
			w02 = wx0*wy2;
			w0i = wx0*wyi;
			w10 = wx1*wy0;
			w11 = wx1*wy1;
			w12 = wx1*wy2;
			w1i = wx1*wyi;
			w20 = wx2*wy0;
			w21 = wx2*wy1;
			w22 = wx2*wy2;
			w2i = wx2*wyi;
			wi0 = wxi*wy0;
			wi1 = wxi*wy1;
			wi2 = wxi*wy2;
			wii = wxi*wyi;
			if ((x0 >= 0) && (x2 < srcImage.rows) && (y0 >= 0) && (y2 < srcImage.cols))
			{
				resultImg.at(i, j) = (srcImage.at(x0, y0)*w00 + srcImage.at(x0, y1)*w01 + srcImage.at(x0, y2)*w02 + srcImage.at(x0, yi)*w0i
					+ srcImage.at(x1, y0)*w10 + srcImage.at(x1, y1)*w11 + srcImage.at(x1, y2)*w12 + srcImage.at(x1, yi)*w1i
					+ srcImage.at(x2, y0)*w20 + srcImage.at(x2, y1)*w21 + srcImage.at(x2, y2)*w22 + srcImage.at(x2, yi)*w2i
					+ srcImage.at(xi, y0)*wi0 + srcImage.at(xi, y1)*wi1 + srcImage.at(xi, y2)*wi2 + srcImage.at(xi, yi)*wii);
			}
		}
	}
	return resultImg;
}

(2)结果
图像算法(一):最近邻插值,双线性插值,三次插值_第4张图片
推荐参考博客:https://me.csdn.net/linqianbi

你可能感兴趣的:(opencv,计算机视觉,图像处理,c++,算法)