ITKeyword,专注技术干货聚合推荐

注册 | 登录

图像缩放插值算法以及matlab简单实现(最近邻法、双线性插值法、三次卷积法)

lihongrui9820 分享于 2014-01-04

推荐:双线性插值的图像缩放算法的研究与实现

 最简单的插值算法是最邻近插值,也称为零阶插值。它输出的像素灰度值就等于距离它映射到的位置最近的输入像素的灰度值,最邻近插值算法简单,在许多情况下都能

2020腾讯云8月秒杀活动,优惠非常大!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1040

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

clear;
close all;  
clc;




CONST=50;
A=imread('testImage\hyf1.bmp');
bwimg=im2bw(A);
resize_img=[];
[srcWidth srcHeight]=size(bwimg);




% %
% 以下算法思路参考http://blog.csdn.net/ArtX/article/details/1540539和http://blog.csdn.net/qiqi5521/article/details/2207562这两篇博客,谢谢博主。
% % 最近邻
% % 思想是根据 srcWidth/dstWidth = srcX/dstY,最后再对srcX取整
% % 缺点是精度不够,严重失真

% dstWidth=srcWidth+CONST*2;
% dstHeight=srcHeight+CONST*2;
% resize_img=zeros(dstWidth,dstHeight);

% % 像素变化公式计算公式
% for i=1:dstWidth
%     for j=1:dstHeight
%     src_i=i*(srcWidth/dstWidth);
%     src_j=j*(srcHeight/dstHeight);
%     resize_img(i,j)=bwimg(round(src_i),round(src_j)); % round四舍五入
%     end
% end

% figure,imshow(bwimg);
% figure,imshow(resize_img)


% % 双线性内插值算法
% % 聪明的方法
% % 最近邻法中根据 srcWidth/dstWidth = srcX/dstY,可以倒退出一个srcX的坐标值,但是这个值是浮点数,
% % 这个浮点数提供了一些信息,它离它在原始图像四周的像素值的关系,根据这个关系,计算一个更接近的dstX,
% % 然后再填充目标图像
% % 公式:
% % f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)vf(i,j+1)+u(1-v)f(i+1,j)+uvf(i+1,j+1)
% % i,j 为浮点坐标的整数部分; u,v为浮点坐标的小数部分
% % 优点:缩放后图像质量高
% % 缺点: 计算量大,双线性插值具有低通滤波器的性质,使高频分量受损,图像轮廓在一定程度上变模糊

% dstWidth=srcWidth+CONST*2;
% dstHeight=srcHeight+CONST*2;
% resize_img=zeros(dstWidth,dstHeight);

% % 像素变化公式计算公式
% for i=1:dstWidth-1
%     for j=1:dstHeight-1
%     src_i=i*(srcWidth/dstWidth);
%     src_j=j*(srcHeight/dstHeight);
%     src_ii=fix(src_i);
%     src_iu=src_i - src_ii; % none fix part
%     src_jj=fix(src_j);
%     src_jv=src_j - src_jj;
%     if src_ii == 0 
%         src_ii=src_ii+1;
%     end
%     if src_jj ==0 
%         src_jj=src_jj+1;
%     end
%     resize_img(i,j)=(1-src_iu)*(1-src_jv)*bwimg(src_ii,src_jj)+(1-src_iu)*src_jv*bwimg(src_ii,src_jj+1)+src_iu*(1-src_jv)*bwimg(src_ii+1,src_jj)...
%         +src_iu*src_jv*bwimg(src_ii+1,src_jj+1);
%     end
% end
% figure,imshow(bwimg);
% figure,imshow(resize_img)




% 三次卷积法
% 三次卷积法计算精度高,但计算亮大,思路是根据一个浮点坐标(i+u,j+v)周围的16个邻点,由下列公式得出目的像素值f(i+u,j+v):

%     f(i+u,j+v) = [A] * [B] * [C]

% [A]=[ S(u + 1) S(u + 0) S(u - 1) S(u - 2) ]

%   ┏ f(i-1, j-1) f(i-1, j+0) f(i-1, j+1) f(i-1, j+2) ┓
% [B]=┃ f(i+0, j-1) f(i+0, j+0) f(i+0, j+1) f(i+0, j+2) ┃
%   ┃ f(i+1, j-1) f(i+1, j+0) f(i+1, j+1) f(i+1, j+2) ┃
%   ┗ f(i+2, j-1) f(i+2, j+0) f(i+2, j+1) f(i+2, j+2) ┛

%   ┏ S(v + 1) ┓
% [C]=┃ S(v + 0) ┃
%   ┃ S(v - 1) ┃
%   ┗ S(v - 2) ┛

%    ┏ 1-2*Abs(x)^2+Abs(x)^3      , 0<=Abs(x)<1
% S(x)={ 4-8*Abs(x)+5*Abs(x)^2-Abs(x)^3 , 1<=Abs(x)<2
%    ┗ 0                , Abs(x)>=2
% 有人说,S(x)是对 Sin(x*Pi)/x
% 的逼近(Pi是圆周率——π),通过极限计算,可以知道Sin(x*Pi)/x的范围在0~pi之间,无法理解为什么要这样设置S(x)
% 但上述求A、B、C的公式还是可以理解,根据双线性插值的思想,也就是根据浮点数在原始坐标中与邻近像素的距离远近来决定原始坐标在目的坐标中所占的比重




dstWidth=srcWidth-CONST*2;
dstHeight=srcHeight-CONST*2;
resize_img=zeros(dstWidth,dstHeight);
A=[];B=[];C=[];




% 像素变化公式计算公式
for i=3:dstWidth-2
    for j=3:dstHeight-2
    src_i=i*(srcWidth/dstWidth);
    src_j=j*(srcHeight/dstHeight);
    src_ii=fix(src_i); % 整数部分
    src_iu=src_i - src_ii; % 小数部分
    src_jj=fix(src_j);
    src_jv=src_j - src_jj;
    
    A=[ cubic_factor(src_iu+1) cubic_factor(src_iu) cubic_factor(src_iu-1) cubic_factor(src_iu-2) ];
    C=[ cubic_factor(src_jv+1); cubic_factor(src_jv); cubic_factor(src_jv-1); cubic_factor(src_jv-2) ];
    B=[ bwimg(src_ii -1,src_jj -1) bwimg(src_ii-1,src_jj) bwimg(src_ii-1,src_jj+1) bwimg(src_ii-1,src_jj+2);...
        bwimg(src_ii,src_jj-1) bwimg(src_ii,src_jj) bwimg(src_ii,src_jj+1) bwimg(src_ii,src_jj+2); ...
        bwimg(src_ii+1,src_jj-1) bwimg(src_ii+1,src_jj) bwimg(src_ii+1,src_jj+1) bwimg(src_ii+1,src_jj+2); ...
        bwimg(src_ii+2,src_jj-1) bwimg(src_ii+2,src_jj) bwimg(src_ii+2,src_jj+1) bwimg(src_ii+2,src_jj+2) ];
    
    resize_img(i,j)=A*B*C;
    
 
    end
end


figure,imshow(bwimg);
figure,imshow(resize_img)




% dstimg=imresize(srcimg,4,'bicubic'); % matlab库函数,调用imresize可以重新生成不同尺寸的图片

推荐:图像缩放--OpenCV cvResize函数--最近邻插值---双线性插值--基本原理

图像大小变换 void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );  src 输入图像. dst 输出图像. interpolation 插值方法: CV

clear; close all;   clc; CONST=50; A=imread('testImage\hyf1.bmp'); bwimg=im2bw(A); resize_img=[]; [srcWidth srcHeight]=size(bwimg); % % % 以下算法思路参考http://blog.csdn.net/ArtX/

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。