• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

MATLAB 图像旋转,双线性插值

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  有好多算法早就想实现了,可是总有各种原因没有实现,这个双线性插值旋转图像就是其中之一。

  之前写过最邻近插值旋转图像,结合着看效果会很好。

 1 clear all;
 2 close all;
 3 clc;
 4 
 5 jiaodu=45;                       %要旋转的角度,旋转方向为顺时针
 6 img=imread(\'lena.jpg\');       %这里v为原图像的高度,u为原图像的宽度
 7 imshow(img);                    %这里y为变换后图像的高度,x为变换后图像的宽度
 8 [h w]=size(img);
 9 
10 theta=jiaodu/180*pi;
11 rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1]; 
12 pix1=[1 1 1]*rot;               %变换后图像左上点的坐标
13 pix2=[1 w 1]*rot;               %变换后图像右上点的坐标
14 pix3=[h 1 1]*rot;               %变换后图像左下点的坐标
15 pix4=[h w 1]*rot;               %变换后图像右下点的坐标
16 
17 height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5]));     %变换后图像的高度
18 width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5]));      %变换后图像的宽度
19 imgn=zeros(height,width);
20 
21 delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]));            %取得y方向的负轴超出的偏移量
22 delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]));            %取得x方向的负轴超出的偏移量
23 
24 for i=1-delta_y:height-delta_y
25     for j=1-delta_x:width-delta_x
26         pix=[i j 1]/rot;                                %用变换后图像的点的坐标去寻找原图像点的坐标,                                         
27                                                             %否则有些变换后的图像的像素点无法完全填充
28         float_Y=pix(1)-floor(pix(1)); 
29         float_X=pix(2)-floor(pix(2));    
30        
31         if pix(1)>=1 && pix(2)>=1 && pix(1) <= h && pix(2) <= w     
32             
33             pix_up_left=[floor(pix(1)) floor(pix(2))];          %四个相邻的点
34             pix_up_right=[floor(pix(1)) ceil(pix(2))];
35             pix_down_left=[ceil(pix(1)) floor(pix(2))];
36             pix_down_right=[ceil(pix(1)) ceil(pix(2))]; 
37         
38             value_up_left=(1-float_X)*(1-float_Y);              %计算临近四个点的权重
39             value_up_right=float_X*(1-float_Y);
40             value_down_left=(1-float_X)*float_Y;
41             value_down_right=float_X*float_Y;
42                                                             
43             imgn(i+delta_y,j+delta_x)=value_up_left*img(pix_up_left(1),pix_up_left(2))+ ...
44                                         value_up_right*img(pix_up_right(1),pix_up_right(2))+ ...
45                                         value_down_left*img(pix_down_left(1),pix_down_left(2))+ ...
46                                         value_down_right*img(pix_down_right(1),pix_down_right(2));
47         end       
48         
49     end
50 end
51 
52 figure,imshow(uint8(imgn))

原图

最邻近插值旋转

双线性插值旋转

后记:

上面的无法通过极限情况,如果旋转为90度或180度,边界会有黑像素。修改如下:

main.m

 1 clear all;
 2 close all;
 3 clc;
 4 
 5 jiaodu=90;                       %要旋转的角度,旋转方向为顺时针
 6 img=imread(\'lena.jpg\');       %这里v为原图像的高度,u为原图像的宽度
 7 imshow(img);                    %这里y为变换后图像的高度,x为变换后图像的宽度
 8 [h w]=size(img);
 9 
10 theta=jiaodu/180*pi;
11 rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1]; 
12 pix1=[1 1 1]*rot;               %变换后图像左上点的坐标
13 pix2=[1 w 1]*rot;               %变换后图像右上点的坐标
14 pix3=[h 1 1]*rot;               %变换后图像左下点的坐标
15 pix4=[h w 1]*rot;               %变换后图像右下点的坐标
16 
17 height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5]));     %变换后图像的高度
18 width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5]));      %变换后图像的宽度
19 imgn=zeros(height,width);
20 
21 delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]));            %取得y方向的负轴超出的偏移量
22 delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]));            %取得x方向的负轴超出的偏移量
23 
24 imgm=img_extend(img,1);     %扩展边界得到的图像
25 
26 for i=1-delta_y:height-delta_y
27     for j=1-delta_x:width-delta_x
28         pix=[i j 1]/rot;                                %用变换后图像的点的坐标去寻找原图像点的坐标,                                         
29                                                             %否则有些变换后的图像的像素点无法完全填充
30         float_Y=pix(1)-floor(pix(1)); 
31         float_X=pix(2)-floor(pix(2));    
32        
33         if pix(1)>=-1 && pix(2)>=-1 && pix(1) <= h+1 && pix(2) <= w+1     
34             
35             pix_up_left=[floor(pix(1)) floor(pix(2))];          %四个相邻的点
36             pix_up_right=[floor(pix(1)) ceil(pix(2))];
37             pix_down_left=[ceil(pix(1)) floor(pix(2))];
38             pix_down_right=[ceil(pix(1)) ceil(pix(2))]; 
39         
40             value_up_left=(1-float_X)*(1-float_Y);              %计算临近四个点的权重
41             value_up_right=float_X*(1-float_Y);
42             value_down_left=(1-float_X)*float_Y;
43             value_down_right=float_X*float_Y;
44                                                             
45             imgn(i+delta_y,j+delta_x)=value_up_left*imgm(pix_up_left(1)+2,pix_up_left(2)+2)+ ...
46                                         value_up_right*imgm(pix_up_right(1)+2,pix_up_right(2)+2)+ ...
47                                         value_down_left*imgm(pix_down_left(1)+2,pix_down_left(2)+2)+ ...
48                                         value_down_right*imgm(pix_down_right(1)+2,pix_down_right(2)+2);
49         end       
50         
51     end
52 end
53 
54 figure,imshow(uint8(imgn))

img_extend.m

 1 function imgm=img_extend(img,r)
 2     [m n]=size(img);
 3 
 4     imgm=zeros(m+2*r+1,n+2*r+1);
 5 
 6     imgm(r+1:m+r,r+1:n+r)=img;
 7     imgm(1:r,r+1:n+r)=img(1:r,1:n); 
 8     imgm(1:m+r,n+r+1:n+2*r+1)=imgm(1:m+r,n:n+r);
 9     imgm(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgm(m:m+r,r+1:n+2*r+1);
10     imgm(1:m+2*r+1,1:r)=imgm(1:m+2*r+1,r+1:2*r);
11 
12 end

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
悟透delphi第二章DELPHI与WIN32时空发布时间:2022-07-18
下一篇:
求助:delphi7+sqlserver2000连接失败发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap