双三次插值法

双三次插值法是常用的一种插值方法 常用于图像或者视频的缩放 假设将图像 A 缩放为图像 B

讲解参考 此、处

是常用的一种插值方法,常用于图像或者视频的缩放。

假设将图像A缩放k倍为图像B。

目标图像B(i, j)处像素值通过图像A矩形网格中最近的十六个采样点的灰度值加权平均得到。

所以需要知道图像B中每一个像素点在图像A中的对应位置。

图像B坐标(i, j)对应于图像A坐标( i / k, j / k),i / k和j / k有可能是小数,设为(x+u,y+v),其中x、y为整数部分,u、v为小数部分。如下图,绿色点p即为图像B(i,j)在图像A对应的位置,a点是16个最近点之一:

双三次插值法

以BiCubic函数作为基函数(其中a一般取 -0.5或-0.75),由此函数算出最近的16个点的权重:

双三次插值法

其中,x代表邻近像素点到p点的距离。例如,a点到p点的距离为(1+u,1+v),所以a点横坐标权重为W(1+u),纵坐标权重为(1+v)。

由此可以求出所有点的横纵坐标权重。

图像B点(i, j)处的值由下列公式得到:

双三次插值法

其中,a(0,0)即为上图a点,Wi代表该点的横坐标权重,Wj代表该点的纵坐标权重。

参考此处代码

Matlab 代码

%BiCubic函数 function A = BiCubic( x ) x = abs(x); %a = -0.5; %a可以不取-0.5 if x <= 1 & x >= 0 %A = (a + 2) * x^3 - (a + 3) * x^2 + 1; A = x^3 - 2 * x^2 + 1; elseif x > 1&&x< 2 %A = a * x^3 - 5 * a * x^2 + 8 * a * x - 4 * a; A = -x^3 + 5 * x^2 - 8 *x + 4; else A = 0; end 
X = imread('D:\Matlab_R2017a\bin\Workspace\banana.jfif'); %载入图片 AA = rgb2gray(X); %转换为灰度图像 [mm, nn] = size(AA); m = mm / 2; n = nn / 2; small = zeros(m, n); %将图像隔行隔列抽取元素,得到缩小的图像 for i = 1 : m for j = 1 : n small(i, j) = AA(i * 2, j * 2); end end k = 5; %设置缩放倍数 % 双三次插值 %将待插值图像矩阵前后各扩展两行两列,共扩展四行四列.防止矩阵索引时溢出的现象 a = small(1, :); c = small(m, :); b = [small(1, 1), small(1, 1), small(:, 1)', small(m, 1), small(m, 1)]; d = [small(1, n), small(1, n), small(: ,n)', small(m, n), small(m, n)]; a1 = [a; a; small; c; c]; b1=[b; b; a1'; d; d]; temp = double(b1'); BB = zeros(k * m, k * n); for i = 1 : k*m %利用公式对新图象像素赋值 for j = 1 : k*n X = i / k + 2; %+2是因为源图像像素矩阵扩展 Y = j / k + 2; x = floor(i / k) + 2; %取整数部分 y = floor(j / k) + 2; u = X - x; %取小数部分 v = Y - y; A = [BiCubic(1 + u) BiCubic(u) BiCubic(1 - u) BiCubic(2 - u)]; %向量化求解 C = [BiCubic(1 + v); BiCubic(v); BiCubic(1 - v); BiCubic(2 - v)]; B = [temp(x - 1, y - 1) temp(x - 1, y) temp(x - 1, y + 1) temp(x - 1, y + 2) temp(x, y - 1) temp(x, y) temp(x, y + 1) temp(x, y + 2) temp(x + 1, y - 1) temp(x + 1, y) temp(x + 1, y + 1) temp(x + 1, y + 2) temp(x + 2, y - 1) temp(x + 2, y) temp(x + 2, y + 1) temp(x + 2, y + 2)]; BB(i, j)=(A * B * C); end end BB = uint8(BB); imshow(uint8(small)); title('缩小的图像'); %显示缩小的图像 figure,imshow(AA); title('原图'); %显示原图像 figure,imshow(BB);title('双三次插值放大的图像'); %显示插值后的图像 mse = 0; AA = double(AA); BB = double(BB); ff2 = fftshift(fft2(AA)); %计算原图像和插值图像的傅立叶幅度谱 g2 = fftshift(fft2(BB)); figure,subplot(1, 2, 1),imshow(log(abs(ff2)), [8, 10]); title('原图像的傅立叶幅度谱'); subplot(1, 2, 2), imshow(log(abs(g2)), [8,10]); title('双三次插值图像的傅立叶幅度谱'); 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
上一篇 2026年3月19日 下午2:25
下一篇 2026年3月19日 下午2:25


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号