首页 > 编程知识 正文

插值法像处理,双三次插值和双线性插值

时间:2023-05-04 00:41:11 阅读:184862 作者:3283

双三次插值
本文将未做插值的原始图像称作源图像,源图像插值缩放K倍后的图像称作目标图像。
以下标识符的意义:

算法
如下图,双三次插值就是通过对周边16个点(A,B,C,…N,O,P)进行加权计算得到目标像素点的值,
(dstX/K,dstY/K)归一化后为(dstX/K,dstY/K),可推得:
srcX=floor(dstX/K);
srcY=floor(dstY/K);
u=dstX/K-srcX;
v=dstY/K-srcY;

这样,就能得到16个点的位置。
加权系数的计算方法有很多种,我采用基于BiCubic基函数的方法,该函数形式如下:

其中,x,y为周围16个源像素点到(dstX/K,dstY/K)的行列方向的距离,
那么,目标像素点的值应为:
实现
本程序是matlab写的一个my_bicubic函数,与matlab自有的imresize的bicubic型函数相对应。可以实现任意倍数的放大。
matlab代码: function [output]=my_bicubic(src,K)%%输入:源图像src,放大倍数K%输出:目标图像矩阵dst [srcM,srcN,srcC]=size(src);%源图像元素点的行列数及色板数dstM=round(K*srcM);%该处仍要确保当放大倍数K非整数时目标图像大小为整数dstN=round(K*srcN); %使用class将数据类型统一,目标图像初始化dst=ones(dstM,dstN,srcC,class(src)); %逐像素点赋值for dstX=1:dstM for dstY=1:dstN X=dstX/K; Y=dstY/K; if X<2||X>srcN-2||Y<2||Y>srcM-2 %在边界采用最近邻插值 for dstC=1:srcC srcX=round(dstX/K); srcY=round(dstY/K); srcX(srcX>srcN)=srcN; %防止索引源图像界外位置,该函数很耗时但简洁 srcX(srcX<1)=1; srcY(srcY>srcM)=srcM ; srcY(srcY<1)=1; dst(dstX,dstY,dstC)=src(srcX,srcY,dstC); end else %非边界位置采用双三次插值 srcX=floor(X);%最近邻左上方像素点位置 srcY=floor(Y); v=X-srcX; u=Y-srcY; X1=zeros(4,4); X2=zeros(4,4); %距离矩阵 W1=ones(4,4); W2=ones(4,4); %系数矩阵 for i=1:4 for j=1:4 X1(i,j)=abs(v-i+2); X2(i,j)=abs(u-j+2); if X1(i,j)<=1 W1(i,j)=1.5*(X1(i,j))^3-2.5*(X1(i,j))^2+1; else if X1(i,j)<2 W1(i,j)=(-0.5)*(X1(i,j))^3+2.5*(X1(i,j))^2-4*X1(i,j)+2; else W1(i,j)=0; end end if X2(i,j)<=1 W2(i,j)=1.5*(X2(i,j))^3-2.5*(X2(i,j))^2+1; else if X2(i,j)<2 W2(i,j)=(-0.5)*(X2(i,j))^3+2.5*(X2(i,j))^2-4*X2(i,j)+2; else W2(i,j)=0; end end end end W=W1.*W2; Z=ones(4,4); %16个源像素点矩阵 O=ones(4,4); %16个加权后的源像素点矩阵 for dstC=1:srcC for i=1:4 for j=1:4 Z(i,j)=src(srcX-1+i-1,srcY-1+j-1,dstC); O(i,j)=W(i,j).*Z(i,j); end end O1=sum(sum(O)); dst(dstX,dstY,dstC)=O1; end end endendoutput=dst;end

评估
分别使用本文函数my_bicubic函数和matlab的imresize函数中的bicubic型对lena图进行2倍放大,并计时。

test代码:

close allfigureA=imread('D:FilesDownloadsDIPpictureLena.jpg');imshow(A);figureticimshow(my_bicubic(A,2));tocfigureticimshow(imresize(A,2,'bicubic'));toc

结果:

右下角边界细节:

由于该算法在边界邻域会越界,所以我采用最近邻法来补充边界,matlab的imresize函数处理得完美,还不知道它是如何处理的,知道了我就更新。
2021.3.18更新:imresize函数应该是以边界为对称轴,对边界像素块做对称拓展,从而使得边界点也能取得周围16个点进行加权计算。

耗时:

综上,处理效果越来越好,但耗时也越来越长。
附:
最近邻插值
双线性插值

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。