matlab彩色图像缩放(双线性与双立方插值)

双线性插值原理可以参考这篇博文:双线性内插法
立方插值的推导我参考的这篇文章:Cubic interpolation
数学推导过程上面两篇文章解释得还是比较清楚,可以自己拿笔推一推,至于双线性和双立方可以理解为先行(或列)插值再列(或行)插值。

程序代码:

双线性插值函数
BilinearInterpolae.m

function imgn = BilinearInterpolae(img,m,n)
    
    %取出单个通道
    imgR = img(:, :, 1);
    [h, w] = size(imgR);
    
    for t= 1:3
        for i = 1:h*m          %新高度,即行
            for j = 1:w*n      %新宽度,即列

                x = i/m;         %坐标(i,j)对应原图中(x,y);x/i=h/(h*m)
                y = j/n;           
                u = x-floor(x); %取得虚坐标x的小数部分 
                v = y-floor(y);

                if x < 1           %,x,y可能对应原图中非整数坐标位置,所以需要进行边界处理
                    x = 1;
                end

                if x > h
                    x = h;
                end

                if y < 1
                    y = 1;
                end

                if y > w
                    y = w;
                end

                %按权重进行双线性插值
                imgn(i,j,t) = img(floor(x), floor(y), t)*(1-u)*(1-v)+ ...
                            img(floor(x), ceil(y), t)* (1-u) * v + ...
                            img(ceil(x), floor(y), t)* u * (1-v) + ...
                            img(ceil(x), ceil(y), t)* u * v;        
            end
        end
    end
end

三次插值函数
cubicInterpolate.m

%----------- p = [p1   p2   p3   p4]-----------
%---------------f(-1) f(0) f(1) f(2)-----------

function value = cubicInterpolate(p,x)   %p的大小4*1
    p = double(p);
    
    a = -0.5*p(1) + 1.5*p(2) - 1.5*p(3) + 0.5*p(4);
    b = p(1) - 2.5*p(2) + 2*p(3) - 0.5*p(4);
    c = 0.5*p(3) - 0.5*p(1);
    d = p(2);
    
    value=a*x^3 + b*x^2 + c*x + d;
end

双立方插值函数(调用三次插值函数)
bicubicInterpolate.m

function revalue=bicubicInterpolate(p,x,y)         %x,y被包含于[0,1]之间

    arr = zeros(4,1);
    for i=1:4
        arr(i) = cubicInterpolate( p(i,1:4), y);   %先行插值
    end
    revalue = cubicInterpolate(arr,x);             %再列插值
    
end

主程序
mian.m

clear all;
close all;
clc;

imgsrc = imread('parrot-1088-725.jpg');
img = imresize(imgsrc, [floor(725/5),floor(1088/5)]);
%imshow(img);

m = 4;            %放大或缩小的宽度的倍数
n = 4;            %放大或缩小的高度的倍数

%取出单个通道
imgR = img(:, :, 1);
[h, w] = size(imgR);

%%双线性插值
imgn2 = BilinearInterpolae(img,4,4);

%%双立方插值
imgn3 = zeros(h*m,w*n);
%初等行变换[rot|E]——>[E|rot']
%rot'=[1/m 0 0;0 1/n 0;0 0 1]
rot = [m 0 0;0 n 0;0 0 1];      

for t = 1:3
    for i = 1:h*m
        for j = 1:w*n
            coord = [i j 1]/rot;          %缩放后的图像像素坐标coordinate在原像素中的坐标pix=[i/m j/n 1]

            u = coord(1)-floor(coord(1)); %x方向(纵轴)虚坐标与左上点实坐标相减的小数部分
            v = coord(2)-floor(coord(2)); %y方向(横轴)虚坐标与左上点实坐标相减的小数部分

            if coord(1) < 2            %边界处理,也可以用卷积时常用的边界扩展防止越界
                coord(1) = 2;
            end

            if coord(1) > h-2
                coord(1) = h-2;
            end

            if coord(2) < 2
                coord(2) = 2;
            end

            if coord(2) > w-2
                coord(2) = w-2;
            end

            x0=floor(coord(1));           %左上角点纵坐标,row
            y0=floor(coord(2));           %左上角点横坐标,col
            
            Rec_pixel = img(x0-1:x0+2, y0-1:y0+2, t);  %虚坐标(x,y)坐标的16邻域的像素
            imgn3(i,j,t) = bicubicInterpolate(Rec_pixel, u, v); %双立方插值      

        end
    end
end

figure(1),imshow(uint8(img));
figure(2);imshow(imgn2);
figure(3);imshow(uint8(imgn3));

原图:
原图
双线性插值效果图
双线性插值效果图双立方插值效果图
双立方插值效果图线性插值和三次插值但从效果上来说我没看出明显的差别,但是理论上应该是三次插值比二次插值好

代码参考了以下两篇博文,部分地方按自己的理解做了修改
https://blog.csdn.net/ywxk1314/article/details/81286413?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2

https://blog.csdn.net/weixin_33895475/article/details/94746783

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值