最近在复习图像算法,对于一些简单的图像算法进行一个代码实现,由于找工作比较忙,具体原理后期补上,先上代码。今天先给出最近邻插值,双线性插值,三次插值。
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)结果:
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)结果:
3.三次插值
基于bicubic函数的权值计算,取a = -0.5
与原图相关的点数为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;
}