今天学习了第三种图像缩放的方法,双三次插值法。由于理解能力比较差,看了好久的公式,还是云里雾里,但是为了督促自己学习,还是把已知的部分记录下来。
数学原理
维基百科的解释


参考这里的博客
k_i_0=W(1+u), k_i_1=W(u), k__i_2=W(1-u), k_i_3=W(2-u);
k_j_0=W(1+v), k_j_1=W(v), k_j_2=W(1-v), k_j_3=W(2-v);
程序实现
/10-9* 功能:双三次插值缩放图片 数学原理:假设原图像A的大小为m*n,新图像B的大小为M*N 如果我们要求B(X,Y)处的像素值: 我们首先可以得到B(X,Y)在图像A中对应的位置(x,y)=(X*(m/M),Y*(N/n)) 这个时候求得的x,y是小数值,我们可以通过这个小数值坐标找到距离最近的16个像素点, 利用所选择的基函数,求出对应的每个像素的权值,最终获得pixelB(X,Y) / #include
#include
#include
using namespace std; using namespace cv; float a = -0.5;//BiCubic基函数 void getW_x(float w_x[4], float x); void getW_y(float w_y[4], float y); int main(){ Mat image = imread("lena.jpg");//源图像 float Row_B = image.rows*2; float Col_B = image.cols*2; Mat biggerImage(Row_B, Col_B, CV_8UC3); for (int i = 2; i < Row_B-4; i++){ for (int j = 2; j < Col_B-4; j++){ float x = i*(image.rows / Row_B);//放大后的图像的像素位置相对于源图像的位置 float y = j*(image.cols / Col_B); /*if (int(x) > 0 && int(x) < image.rows - 2 && int(y)>0 && int(y) < image.cols - 2){*/ float w_x[4], w_y[4];//行列方向的加权系数 getW_x(w_x, x); getW_y(w_y, y); Vec3f temp = { 0, 0, 0 }; for (int s = 0; s <= 3; s++){ for (int t = 0; t <= 3; t++){ temp = temp + (Vec3f)(image.at
(
int(x) + s -
1,
int(y) + t -
1))*w_x[s] * w_y[t]; } } biggerImage.at
(i, j) = (Vec3b)temp; } } imshow(
"image", image); imshow(
"biggerImage", biggerImage); waitKey(
0);
return
0; }
/*计算系数*/
void getW_x(
float w_x[
4],
float x){
int X = (
int)x;
//取整数部分
float stemp_x[
4]; stemp_x[
0] =
1 + (x - X); stemp_x[
1] = x - X; stemp_x[
2] =
1 - (x - X); stemp_x[
3] =
2 - (x - X); w_x[
0] = a*
abs(stemp_x[
0] * stemp_x[
0] * stemp_x[
0]) -
5 * a*stemp_x[
0] * stemp_x[
0] +
8 * a*
abs(stemp_x[
0]) -
4 * a; w_x[
1] = (a +
2)*
abs(stemp_x[
1] * stemp_x[
1] * stemp_x[
1]) - (a +
3)*stemp_x[
1] * stemp_x[
1] +
1; w_x[
2] = (a +
2)*
abs(stemp_x[
2] * stemp_x[
2] * stemp_x[
2]) - (a +
3)*stemp_x[
2] * stemp_x[
2] +
1; w_x[
3] = a*
abs(stemp_x[
3] * stemp_x[
3] * stemp_x[
3]) -
5 * a*stemp_x[
3] * stemp_x[
3] +
8 * a*
abs(stemp_x[
3]) -
4 * a; }
void getW_y(
float w_y[
4],
float y){
int Y = (
int)y;
float stemp_y[
4]; stemp_y[
0] =
1.0 + (y - Y); stemp_y[
1] = y - Y; stemp_y[
2] =
1 - (y - Y); stemp_y[
3] =
2 - (y - Y); w_y[
0] = a*
abs(stemp_y[
0] * stemp_y[
0] * stemp_y[
0]) -
5 * a*stemp_y[
0] * stemp_y[
0] +
8 * a*
abs(stemp_y[
0]) -
4 * a; w_y[
1] = (a +
2)*
abs(stemp_y[
1] * stemp_y[
1] * stemp_y[
1]) - (a +
3)*stemp_y[
1] * stemp_y[
1] +
1; w_y[
2] = (a +
2)*
abs(stemp_y[
2] * stemp_y[
2] * stemp_y[
2]) - (a +
3)*stemp_y[
2] * stemp_y[
2] +
1; w_y[
3] = a*
abs(stemp_y[
3] * stemp_y[
3] * stemp_y[
3]) -
5 * a*stemp_y[
3] * stemp_y[
3] +
8 * a*
abs(stemp_y[
3]) -
4 * a; }
注:由于作者编程能力有限,希望有人能指正一下怎么优化这里的程序,这个程序只是实现了算法,运行
速度慢的要死不能忍受!
效果展示


发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215356.html原文链接:https://javaforall.net
