博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
matlab练习程序(图像旋转,双线性插值)
阅读量:6375 次
发布时间:2019-06-23

本文共 5001 字,大约阅读时间需要 16 分钟。

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

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

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                   endendfigure,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                   endendfigure,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

 

转载于:https://www.cnblogs.com/tiandsp/archive/2012/12/03/2800373.html

你可能感兴趣的文章
2、Gerrit配置--用户配置
查看>>
Centos7 Nginx 服务器的安装配置
查看>>
Backtrack5 网络漏洞攻击工具 Metasploit
查看>>
Hibernate学习(八):检索方式
查看>>
RIPv1 PK RIPv2
查看>>
基于WorsPress+Xampp搭建博客
查看>>
noclobber:避免文件的重写
查看>>
Weblogic多应用部署在一个域下导致session冲突
查看>>
安装Centos6 分区时出现缺少/boot/efi 经验分享
查看>>
浅析Happyhour的适用性
查看>>
利用Oracle VPD实现行级安全保护(一)
查看>>
Spring中数据绑定的两种方式(BeanWrapperImpl或者DataBinder)
查看>>
一个关于Cobar 的释疑
查看>>
Outlook 2007对于不同(Gmail.Sina.Sohu.126.163.Yahoo.Hotmail)Email账号设置
查看>>
NUMA与英特尔下一代Xeon处理器学习心得(9)
查看>>
Inter VLAN routing router on GNS3
查看>>
一个简单的密码学实例
查看>>
Vlan配置详解之单臂路由
查看>>
沟通的艺术之幻灯片这奇女子
查看>>
【一天一个shell命令】文本内容操作系列-awk补充二(函数)
查看>>