Matlab实现图像插值和降低图像灰度级

###图像在旋转或者缩放操作时候会需要插值操作,插值操作就是在像素间插入未知的像素值。
###常见的插值算法有最近邻插值算法,双线性插值算法,三次卷积等

###最近邻插值算法
这是最简单的一种插值算法,根据目标图像(插值后的图像大小)与源图像大小的比值来寻找目标图像的像素位置对应于源图像像素的位置。
比如说源图像是33的大小,插值后的目标图像数44的大小
目标图像G(i,j)代表第i行j列的像素值,我们现在要从源图像中找到对应的像素来填补目标G(i,j)的值。
设源图像的大小为srcxsrcy,目标图像的大小为desxdesy,缩放比为factor
那么目标图像G(i,j)处对应的源图像位置为F(i*(desx/factor),j*(desy/factor))
其中desx/factor可以做向下取整运算,因为坐标位置都是整数

Matlab简单实现
function imt=change_pixels(ima,factor)
[xs,ys] = size(ima);
if factor<0               % shrink the image
    fa = abs(factor)       
    %imt = zeros((xs/fa),(xs/fa));  
    for i=1:(xs/fa)
        for j=1:(ys/fa)
            imt(i,j) = ima(i*fa,j*fa);
        end
    end
else if factor>0           %amplify th image
        for i=1:(xs*factor)
            for j=1:(ys*factor)
                imt(i,j) = ima(ceil(i/factor),ceil(j/factor));  

            end
        end
    else 
        imt = ima;
    end
end
return;

最近邻插值算法放大图像
[外链图片转存失败(img-EcuPtrNB-1568455044377)(https://img-blog.csdn.net/20170331171422157?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2lsZW5jZTIwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]


###双线性插值算法
最近邻插值算法只是通过源图像一个点的像素值来填充目标图像的值,这在放大倍数大了以后造成失真。双线性插值算法通过计算源图像四个点的像素值来填充目标像素,并且采用加权计算的方法使得四个点对填充点的像素都贡献不一样,这其中也顺带了平滑滤波的效果,使得插值后的图像看起来稍微模糊一点。在计算量上双线性插值算法比最近邻插值算法大。
对于一个目标像素,试着坐标反向变化得到的是浮点坐标(i+u,j+v),其中i,j均为浮点坐标的整数部分,u,v均为浮点数的小数部分,这个像素f(i+u,j+v)可由原图像的四个坐标(i,j),(i+1,j+1),(i+1.j)(i,j+1)来获得。
这里写图片描述

现在假如目标图的象素坐标为(1,1),那么反推得到的对应于源图的坐标是(0.75 , 0.75),
这其实只是一个概念上的虚拟象素,实际在源图中并不存在这样一个象素,那么目标图的象素(1,1)的取值不能够由这个虚拟象素来决定,而只能由源图的这四
个象素共同决定:(0,0)(0,1)(1,0)(1,1),而由于(0.75,0.75)离(1,1)要更近一些,那么(1,1)所起的决定作用更大一
些,这从公式1中的系数uv=0.75×0.75就可以体现出来,而(0.75,0.75)离(0,0)最远,所以(0,0)所起的决定作用就要小一些,
公式中系数为(1-u)(1-v)=0.25×0.25也体现出了这一特点

双线性插值算法matlab简易实现

function img=change_size(imgpath,xs,ys)
% this function is design to amplify or shink an image
f=imread(imgpath);
[m,n]=size(f);
x_rate=xs/m;
y_rate=ys/n;
img=zeros(xs,ys);
if x_rate>=1 && y_rate>=1 % amplify imge in x and y axis
    for i=1:xs
        for j=1:ys
            srcx=i/x_rate;
            srcy=j/y_rate;
           
            srcx_int=floor(srcx);
            srcx_decimal=srcx-srcx_int;
            
            srcy_int=floor(srcy);
            srcy_decimal=srcy-srcy_int;
            
             if srcx_int==0
                srcx_int=1;
             else if srcx_int>=m
                     srcx_int=m-1;
                 end
             
            end
             if srcy_int==0
                srcy_int=1;
             else if srcy_int>=n
                     srcy_int=n-1;
                 end
             end

           img(i,j)=srcx_decimal*srcy_decimal*f(srcx_int+1,srcy_int+1)+(1-srcx_decimal)*(1-srcy_decimal)*f(srcx_int,srcy_int)...
                +srcx_decimal*(1-srcy_decimal)*f(srcx_int,srcy_int+1)+(1-srcx_decimal)*srcy_decimal*f(srcx_int+1,srcy_int);
                
        end
        
          
    end
end



if x_rate<=1 && y_rate<=1 % amplify imge in x and y axis
    for i=1:xs
        for j=1:ys
            srcx=i/x_rate;
            srcy=j/y_rate;
           
            srcx_int=floor(srcx);
            srcx_decimal=srcx-srcx_int;
            
            srcy_int=floor(srcy);
            srcy_decimal=srcy-srcy_int;
            
             if srcx_int==0
                srcx_int=1;
             else if srcx_int>=m
                     srcx_int=m-1;
                 end
             
            end
             if srcy_int==0
                srcy_int=1;
             else if srcy_int>=n
                     srcy_int=n-1;
                 end
             end
            img(i,j)=srcx_decimal*srcy_decimal*f(srcx_int,srcy_int)+(1-srcx_decimal)*(1-srcy_decimal)*f(srcx_int+1,srcy_int+1)...
                +srcx_decimal*(1-srcy_decimal)*f(srcx_int+1,srcy_int)+(1-srcx_decimal)*srcy_decimal*f(srcx_int,srcy_int+1);
            
        end
    end
end
img=uint8(img);
end

其中该代码功能局限性很大,而且我发现经过双线性插值后的图像有锯齿状的像素块,分析很久没发现原因

双线性插值算法放大图像
[外链图片转存失败(img-x8j4fJUw-1568455044379)(https://img-blog.csdn.net/20170331171457604?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2lsZW5jZTIwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

三次卷积就引入更多领近的像素来计算像素值,精度当然很高,但是计算量也大很多。


###降低图像灰度级

我们知道,图像分很多灰度级,灰度级越大,所呈现的图像月丰富,所能表现的颜色跨度也越大。
这儿本文以8bits的灰度图像为例子,实现灰度级的降低

function changereduce_factor(imgpath,reduce_factor)
% Write a computer program capable of reducing the number of intensity levels in an image from 256 to 2, 
% in integer powers of 2. The desired number of intensity levels needs to be a variable input to your program.
    f = imread(imgpath);
    if reduce_factor<0
        reduce_factor=0
    else if reduce_factor>8
            reduce_factor=8
        end
    end

    dfactor=uint8(2^reduce_factor);
    f_trans=(f/dfactor)*dfactor;
    subplot(1,2,1);
    imshow(f);
    subplot(1,2,2);
    imshow(f_trans);
    
end

本实验是以2的幂次方来降低图像的灰度。
dfactor=uint8(2^reduce_factor);
f_trans=(f/dfactor)*dfactor;
是先根据降低的灰度级除以原始图像像素大小,得到整数,去除小数部分。然后在乘以降低的灰度级来量化图像,就得到了降低灰度级后的图像。

这里写图片描述

参考文献:liyuefeilong的专栏图像差值算法

  • 8
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值