matlab練習程序(圖像旋轉,雙線性插值)


  有好多算法早就想實現了,可是總有各種原因沒有實現,這個雙線性插值旋轉圖像就是其中之一。

  之前寫過最鄰近插值旋轉圖像,傳送門。結合着看效果會很好。

clear all;
close all;
clc;

jiaodu=45;                       %要旋轉的角度,旋轉方向為順時針
img=imread('lena.jpg');       %這里v為原圖像的高度,u為原圖像的寬度
imshow(img);                    %這里y為變換后圖像的高度,x為變換后圖像的寬度
[h w]=size(img);

theta=jiaodu/180*pi;
rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1]; 
pix1=[1 1 1]*rot;               %變換后圖像左上點的坐標
pix2=[1 w 1]*rot;               %變換后圖像右上點的坐標
pix3=[h 1 1]*rot;               %變換后圖像左下點的坐標
pix4=[h w 1]*rot;               %變換后圖像右下點的坐標

height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5]));     %變換后圖像的高度
width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5]));      %變換后圖像的寬度
imgn=zeros(height,width);

delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]));            %取得y方向的負軸超出的偏移量
delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]));            %取得x方向的負軸超出的偏移量

for i=1-delta_y:height-delta_y
    for j=1-delta_x:width-delta_x
        pix=[i j 1]/rot;                                %用變換后圖像的點的坐標去尋找原圖像點的坐標,                                         
                                                            %否則有些變換后的圖像的像素點無法完全填充
        float_Y=pix(1)-floor(pix(1)); 
        float_X=pix(2)-floor(pix(2));    
       
        if pix(1)>=1 && pix(2)>=1 && pix(1) <= h && pix(2) <= w     
            
            pix_up_left=[floor(pix(1)) floor(pix(2))];          %四個相鄰的點
            pix_up_right=[floor(pix(1)) ceil(pix(2))];
            pix_down_left=[ceil(pix(1)) floor(pix(2))];
            pix_down_right=[ceil(pix(1)) ceil(pix(2))]; 
        
            value_up_left=(1-float_X)*(1-float_Y);              %計算臨近四個點的權重
            value_up_right=float_X*(1-float_Y);
            value_down_left=(1-float_X)*float_Y;
            value_down_right=float_X*float_Y;
                                                            
            imgn(i+delta_y,j+delta_x)=value_up_left*img(pix_up_left(1),pix_up_left(2))+ ...
                                        value_up_right*img(pix_up_right(1),pix_up_right(2))+ ...
                                        value_down_left*img(pix_down_left(1),pix_down_left(2))+ ...
                                        value_down_right*img(pix_down_right(1),pix_down_right(2));
        end       
        
    end
end

figure,imshow(uint8(imgn))

原圖

最鄰近插值旋轉

雙線性插值旋轉

后記:

上面的無法通過極限情況,如果旋轉為90度或180度,邊界會有黑像素。修改如下:

main.m

clear all;
close all;
clc;

jiaodu=90;                       %要旋轉的角度,旋轉方向為順時針
img=imread('lena.jpg');       %這里v為原圖像的高度,u為原圖像的寬度
imshow(img);                    %這里y為變換后圖像的高度,x為變換后圖像的寬度
[h w]=size(img);

theta=jiaodu/180*pi;
rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1]; 
pix1=[1 1 1]*rot;               %變換后圖像左上點的坐標
pix2=[1 w 1]*rot;               %變換后圖像右上點的坐標
pix3=[h 1 1]*rot;               %變換后圖像左下點的坐標
pix4=[h w 1]*rot;               %變換后圖像右下點的坐標

height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5]));     %變換后圖像的高度
width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5]));      %變換后圖像的寬度
imgn=zeros(height,width);

delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]));            %取得y方向的負軸超出的偏移量
delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]));            %取得x方向的負軸超出的偏移量

imgm=img_extend(img,1);     %擴展邊界得到的圖像

for i=1-delta_y:height-delta_y
    for j=1-delta_x:width-delta_x
        pix=[i j 1]/rot;                                %用變換后圖像的點的坐標去尋找原圖像點的坐標,                                         
                                                            %否則有些變換后的圖像的像素點無法完全填充
        float_Y=pix(1)-floor(pix(1)); 
        float_X=pix(2)-floor(pix(2));    
       
        if pix(1)>=-1 && pix(2)>=-1 && pix(1) <= h+1 && pix(2) <= w+1     
            
            pix_up_left=[floor(pix(1)) floor(pix(2))];          %四個相鄰的點
            pix_up_right=[floor(pix(1)) ceil(pix(2))];
            pix_down_left=[ceil(pix(1)) floor(pix(2))];
            pix_down_right=[ceil(pix(1)) ceil(pix(2))]; 
        
            value_up_left=(1-float_X)*(1-float_Y);              %計算臨近四個點的權重
            value_up_right=float_X*(1-float_Y);
            value_down_left=(1-float_X)*float_Y;
            value_down_right=float_X*float_Y;
                                                            
            imgn(i+delta_y,j+delta_x)=value_up_left*imgm(pix_up_left(1)+2,pix_up_left(2)+2)+ ...
                                        value_up_right*imgm(pix_up_right(1)+2,pix_up_right(2)+2)+ ...
                                        value_down_left*imgm(pix_down_left(1)+2,pix_down_left(2)+2)+ ...
                                        value_down_right*imgm(pix_down_right(1)+2,pix_down_right(2)+2);
        end       
        
    end
end

figure,imshow(uint8(imgn))

img_extend.m

function imgm=img_extend(img,r)
    [m n]=size(img);

    imgm=zeros(m+2*r+1,n+2*r+1);

    imgm(r+1:m+r,r+1:n+r)=img;
    imgm(1:r,r+1:n+r)=img(1:r,1:n); 
    imgm(1:m+r,n+r+1:n+2*r+1)=imgm(1:m+r,n:n+r);
    imgm(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgm(m:m+r,r+1:n+2*r+1);
    imgm(1:m+2*r+1,1:r)=imgm(1:m+2*r+1,r+1:2*r);

end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM