DSP

图像降采样和升采样

2019-07-13 12:26发布

转自:http://www.lofter.com/postentry?from=search&permalink=1cb3111d_6ee9587 1、先说说这两个词的概念: 
降采样,即是采样点数减少。对于一幅N*M的图像来说,如果降采样系数为k,则即是在原图中 每行每列每隔k个点取一个点组成一幅图像。降采样很容易实现. 
升采样,也即插值。对于图像来说即是二维插值。如果升采样系数为k,即在原图n与n+1两点之间插入k-1个点,使其构成k分。二维插值即在每行插完之后对于每列也进行插值。 
插 值的方法分为很多种,一般主要从时域和频域两个角度考虑。对于时域插值,最为简单的是线性插值。除此之外,Hermite插值,样条插值等等均可以从有关 数值分析书中找到公式,直接代入运算即可。对于频域,根据傅里叶变换性质可知,在频域补零等价于时域插值。所以,可以通过在频域补零的多少实现插值运 算。 

2、实现 
其实在matlab中自带升采样函数(upsample)和降采样函数(downsample),读者可以查找matlab的帮助文件详细了解这两个函数。在这里,我重新写如下: 
%======================================================== 
%   Name: usample.m 
%   功能:升采样 
%   输入:采样图片 I, 升采样系数N 
%   输出:采样后的图片Idown 
%   author:gengjiwen    date:2015/5/10 
%======================================================== 
function Iup = usample(I,N) 
[row,col] = size(I); 
upcol = col*N; 
upcolnum = upcol - col; 
uprow = row*N; 
uprownum = uprow -row; 

If = fft(fft(I).').';     %fft2变换 
Ifrow = [If(:,1:col/2) zeros(row,upcolnum) If(:,col/2 +1:col)];   %水平方向中间插零 
                                                                                                   %补零之后,Ifrow为 row*upcol                                                                
Ifcol = [Ifrow(1:row/2,:);zeros(uprownum,upcol);Ifrow(row/2 +1:row,:)];   %垂直方向补零 
Iup = ifft2(Ifcol); 
end 
%======================================================== 
%   Name: dsample.m 
%   功能:降采样 
%   输入:采样图片 I, 降采样系数N 
%   输出:采样后的图片Idown 
%   author:gengjiwen    date:2015/5/10 
%======================================================== 
function Idown = dsample(I,N) 
[row,col] = size(I); 
drow = round(row/N); 
dcol = round(col/N); 
Idown = zeros(drow,dcol); 
p =1; 
q =1; 
for i = 1:N:row 
    for j = 1:N:col 
         Idown(p,q) = I(i,j); 
         q = q+1; 
    end 
    q =1; 
    p = p+1; 
end 
end 
% =========================================== 
% 测试升采样和降采样的程序 
%  author:gengjiwen , date:2015/05/10 
%  备注:测试完毕! 
%============================================ 
clear; 
close all; 
I = imread('test1.jpg'); 
I = rgb2gray(I); 
figure(1); 
imagesc(I); 
title('原图像'); 
% 图像降采样 
 figure; 
for ii = 2:2:8 
 Idown = dsample(I,ii); 
 subplot(2,2,ii/2); 
 imagesc(Idown); 
 str = ['downsample at N = ' num2str(ii)]; 
 title(str); 
end 
% 图像升采样 
 figure; 
for ii = 2:2:8 
 Iup =usample(I,ii); 
 subplot(2,2,ii/2); 
 imagesc(abs(Iup)); 
 str = ['upsample at N = ' num2str(ii)]; 
 title(str); 
end 
测试结果如下: 
       3、结果分析 
降采样没什么可说的,其实在matlab中可以很方便的用冒号运算符实现,具体可以查看下matlab自带函数downsample的实现。 
对 于升采样,这里用了频域方法实现。将原图像进行二维傅里叶变换,之后在变换后的中间补零插值,再反变换回时域。根据傅里叶变换性质可知,此时的时域插值核 sinc函数的形式,对于二维,应是 二维sinc()函数。由于sinc函数的旁瓣比较大,故在升采样后的图像中会存在振铃现象。读者可以观察上面的实现结果图片。如果想减小这种情况,则可 以对其进行频域加窗。