基于双线性插值算法实现图像缩放原理及MATLAB实现

双线性插值实现图像缩放

ModelEngine·创作计划征文活动 10w+人浏览 1.4k人参与

目录

1.单线性插值算法

2.双线性插值算法

3.使用双线性插值算法实现图像的缩放【MATLAB】


1.单线性插值算法

已知P0(x0,y0),P1(x1,y1)两个相邻点(x1-x0=1,y1-y0=1),要求P(x,y)

可以列出如下方程式:

整理后得

将x看成是像素点排序值,y看成是对应的像素点值,记y1=pixel_x1,y0=pixel_x0,y=pixel_x

pixel_x=(x1-x)*pixel_x0 + (x-x0)*pixel_x1

令x-x0=x_weight,

整理有pixel_x = (1-x_weight)*pixel_x0 + x_weight * pixel_x1

2.双线性插值算法

已知缩放前的原图宽高为SRC_WIDTH,SRC_HIGH,记(SRC_WIDTH,SRC_HIGH)

已知缩放后的目标宽高为DST_WIDTH,DST_HIGH,记(DST_WIDTH,DST_HIGH)

已知目标图的一个点为(x_dst,y_dst),要求其映射到原图的映射点(x_map,y_map)

根据上述已知条件,可列公式:

整理有:

一般以像素点的中心表示像素坐标,则第i行,第j列的坐标为(i+0.5,j+0.5)

那么上述公式整理为:

那么P(x_map,y_map)就是所求的在原图的映射点

根据映射点求最近的四个像素点

向下取x_map,y_map的整数值:

x0=floor(x_map), y0=floor(y_map)

得到Q0(x0,y0),根据Q0求得Q1(x0+1,y0),Q2(x0,y0+1),Q3(x0+1,y0+1)

通过Q0,Q1,Q2,Q3,经过两次线性插值算法,求得P1_y,P2_y,再由P1_y,P2_y求得P_y,这个P_y就是在目标图像上的像素值

由单线性插值算法可知:

P1_y = Q0 * (1-x_weight) + Q1 * x_weight

P2_y = Q2 * (1-x_weight) + Q3 * x_weight

P_y = (1-y_weight)*P1_y + y_weight * P2_y

整理有

P_y =  (1-y_weight)*(1-x_weight)*Q0 + (1-y_weight)*x_weight * Q1+ y_weight * (1-x_weight) *Q2 +y_weight * x_weight * Q3

3.使用双线性插值算法实现图像的缩放【MATLAB】

clc;
clear all;

%双线性插值算法
%对彩色图进行的缩放操作

DST_HIGH = 1024;
DST_WIDTH = 1024;

src_img = imread('D:\bilinear\yu.bmp');  %将RGB数据转化为灰度数据,也就是将512*521*3的矩阵转换为512*512*1的矩阵保存
src_img_r = rgb2gray(src_img);


[SRC_HIGH,SRC_WIDTH] = size(src_img_r);

dst_img = zeros(DST_HIGH,DST_WIDTH,3);

for t = 1:3
   for y_dst = 1 : DST_HIGH
     for x_dst = 1 : DST_WIDTH                                               %求目标像素
        x_map = ((x_dst - 1) ) * (SRC_WIDTH - 1) / (DST_WIDTH - 1) - 0.5;    %-1 -0.5是解决边缘白边,黑边问题
        y_map = ((y_dst - 1) ) * (SRC_HIGH - 1)  / (DST_HIGH - 1) - 0.5;
        
        if( x_map < 0 )
            x0 = 0;
        else
            x0 = floor(x_map);    %向下取整
        end
        
        if( y_map < 0 )
            y0 = 0;
        else
            y0 = floor(y_map);
        end
        
        if(x0 >= SRC_WIDTH - 1  || y0 >= SRC_HIGH - 1 )                      %超出目标区域取0值
            dst_img(y_dst , x_dst , t) = 0;
        else
            x_weight = x_map - x0;
            y_weight = y_map - y0;
            
            Q0_weight = (1 - y_weight) * (1- x_weight); 
            Q0 = src_img(y0 + 1 , x0 + 1 , t);                  %图像是从1开始
            
            Q1_weight = (1 - y_weight) * x_weight;      
            Q1 = src_img(y0 + 1 , x0 + 2 , t);
            
            Q2_weight = y_weight * (1- x_weight);       
            Q2 = src_img(y0 + 2 , x0 + 1 , t);
            
            Q3_weight =  y_weight * x_weight;           
            Q3 = src_img(y0 + 2 , x0 + 2 , t);
        
            dst_img(y_dst,x_dst,t) = Q0_weight * Q0 + Q1_weight * Q1 + Q2_weight * Q2 + Q3_weight * Q3;
           end
       end
   end
end

dst_img = uint8(dst_img);

subplot(211); imshow(src_img);             %输出原图像
subplot(212); imshow(dst_img);             %输出经过缩放后的图像

imwrite(dst_img, 'D:\bilinear\yu_rgb.bmp');

仅供学习使用,请勿转载

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值