关于双线性变换法为何要拓展和网上许多人程序(MATLAB)中减一操作的讨论

这篇博客详细探讨了在数字图像处理中使用双线性插值法进行放大和缩小操作的问题。作者指出,为了确保变换的准确性,需要在原图边界外拓展一圈。在进行插值时,由于双线性变换依赖于四个相邻像素,因此需要对坐标进行修正,即减一操作。减一在放大操作中可能导致最后一行和列未被处理,但在大尺寸图像中影响微乎其微。此外,博客还通过代码示例展示了如何实现双线性插值,并解释了减一操作在缩小操作中的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做数字图像处理的作业,学双线性插值法,编出来错误。发现网上许多代码和自己编的不一样,但自己的却能完美运行。
其中,有两个问题:
一是要在原图外面拓展一圈,这是因为,双线性变换法是靠周围四个点来确定里面的点,而你新的图像的四条边本身就是边界,去哪里找四个点。所以要在外面拓展一圈,能使得变换后得到的点就是边界的点。
二是许多人代码里面的

%% Step4 由新图像的某个像素(zi,zj)映射到原始图像(ii,jj)处,并插值。
for zj = 1:ZIW % 对图像进行按列逐元素扫描
for zi = 1:ZIH
ii = (zi-1)/zmf; jj = (zj-1)/zmf;
i = floor(ii); j = floor(jj); % 向下取整
u = ii - i; v = jj - j;
i = i + 1; j = j + 1;
ZI(zi,zj,:) = (1-u)(1-v)IT(i,j,:) +(1-u)vIT(i,j+1,:)…
+ u
(1-v)IT(i+1,j,:) +uv
IT(i+1,j+1,:);
end
end

ii = (zi-1)/zmf; jj = (zj-1)/zmf;

这个部分为啥要减一?
如果不减一,那在进行放大操作时,会很完美,即确实不用减一,获得的图像就很完美。
放大操作,完美绘制
那为何还要减一呢?因为双线性变换法不仅仅可以进行放大操作,还能进行缩小操作,即把放大系数改为0-1的小数。而在此时,你运行程序就会报错。
但改为减一以后,程序就能完美运行,不过减一操作,确实使得最后一行和最后一列并未放大和缩小。(其实是由于前面的拓展操作后的图像,是原图像边界扩大一像素,使得你在进行缩小操作,即间隔选行列时,刚好与你原图该选的行列错开,左边多选了一列,右边少选了一列。我在后面会给出程序,大家可以看下工作区里面矩阵值)
减一放大操作
减一放大操作

减一缩小操作
减一缩小操作

那最后一列被忽视,为何还要减一操作呢?因为你做的图片往往大于500*500像素,一列变化你肉眼看不出。所以虽然减一后放大缩小的图像与理论获得的其实是有误差的,但可以忽略不计。

matlab脚本如下,ceshi.jpg图片你可以自己选择,如果要像我这里看最后一列被忽视的图。可以自己写个矩阵。
eg:

ceshi1=zeros(17,17,3);
ceshi1(3:15,3:15,:)=255;
ceshi1(6:12,6:12,:)=0;
ceshi1=uint8(ceshi1);

直接用这个ceshi1变量来代替img就行。

// An highlighted block
clc;clear all;close all;
format compact
img=imread('ceshi.jpg');
%双线性插值法只能扩大
R=0.5;  % 输入图像文件及放大率
[row,col,color] = size(img);    % 获得图像的行列数及色板数
new_row = round(row*R);     % 新图像行
new_col = round(col*R);     % 新图像列
% 新图像初始化
% 使用class获得原图像的数据类型,使得新图像数据类型与原图像保持一致
img_new = zeros(new_row,new_col,color,class(img));

%reference:https://blog.csdn.net/huang1024rui/article/details/46545329没拓展,会报错,维度不对
%双线性插值是用待求值点周围四个点的值来计算的,当新图像上的像素点映射到原图像的边界时,边界扩展保证了计算能正确进行,而不会溢出。
IT = zeros(row+2,col+2,color);
IT(2:row+1,2:col+1,:) = img;
IT(1,2:col+1,:)=img(1,:,:);IT(row+2,2:col+1,:)=img(row,:,:);%四条边填充
IT(2:row+1,1,:)=img(:,1,:);IT(2:row+1,col+2,:)=img(:,col,:);
IT(1,1,:) = img(1,1,:);IT(1,col+2,:) = img(1,col,:);%四个点填充
IT(row+2,1,:) = img(row,1,:);IT(row+2,col+2,:) = img(row,col,:);
% 对新图像的行、列、色板赋值
for i = 1:new_row
    for j = 1:new_col
            x=(i-1)/R;%此处不减一,当图像缩小,即R<1时,会报错
            y=(j-1)/R;%同样,减一后,放大时,原图最后一列未加倍,但像素点多的图像你也看不清最后一点,可以选择ceshi图像来看变化
%             x=i/R;%也就是说,放大时,可以不减一,这是正确的。而减一法放大缩小都适用,虽然放大时最后一列元素没加倍,但看不出影响
%             y=j/R;
            X=floor(x);
            Y=floor(y);
            u=x-X;
            v=y-Y;
            X=X+1;
            Y=Y+1;
            img_new(i,j,:)=IT(X,Y,:)*(1-u)*(1-v)+IT(X,Y+1,:)*u*(1-v)...
                +IT(X+1,Y,:)*(1-u)*v+IT(X+1,Y+1,:)*u*v;
    end
end

% 显示原图像
subplot(1,2,1);imshow(img);title('Original Image');axis on
% 显示新图像
subplot(1,2,2);imshow(img_new);title('New Image');axis on
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值