前一段时间做图像处理,现在一点点整理下来吧,算是个记录,也希望大家能批评指正。
图像的旋转,主要是分三步
1、计算旋转后图像的大小;
2、计算旋转后图像的坐标;
3、对盲点进行插值;
1.计算旋转后图像的大小:
这个挺简单的,拿顺时针转为例子,假设原图像大小为m×n,旋转后为m1×n1;旋转角度为θ,
m1=m×cosθ+n×sinθ,
n1=m×sinθ+n×cosθ,
然后用m1和n1构造一个零矩阵就行了。
2.计算旋转后图像的坐标。
我是以图像的中心旋转的,公式推起来有点复杂。等明天补上推导的图吧。
核心公式是X=x*cosθ+y*sinθ,Y=x*sinθ-y*cosθ,
其中x,y分别是原图像的坐标减去原图像中心点之差,X,Y分别是旋转后图像的坐标减去旋转后图像中心点之差。
旋转后实际坐标为X,Y分别加上旋转后图像中心点的坐标。
这一步后出来的图像就是这样
由于是QQ截图色彩效果不好,但是可以看到有恒多盲点,就是哪些小黑点。
这就需要插值,把这些小黑点补上。这些小黑点是怎么来的呢,主要是在坐标变换的时候,原图像的坐标都是整数,在变换后产生小数,然后再取整,这个过程会丢失一些点。
所以就有了这些小黑点。
3.插值,插值的方法有很多,效果也不一样,最简单的插值就是临近像素点的插值。插值完以后效果是这样
原图是这样
跟原图比较,明显在边缘有很多毛刺,所以 好的插值方法是旋转图像的关键。以后可以慢慢研究
下面附上MATLAB源码
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %函数功能:以图像为远点右转函数,插值方法:双线性插值%%%%
- %作者:张小胖话不多%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %时间:2013.9.26%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- clear all;close all; clc;
- %%%%dst=my_img_rotate(I,theta)
- src=imread('D:\Documents\Desktop\lenna.JPG'); %%%%读入原图像;
- theta=pi/6;
- [m,n,q]=size(src) %%%%%计算原图像的大小
- A=[cos(theta),sin(theta);sin(theta),cos(theta)]; %%%%%%%%%%%计算图像旋转后大小的变换公式
- C=[m,n]*A; %%%%%%%%%%%计算图像旋转后大小
- m2=ceil(C(1))+1;n2=ceil(C(2))+1; %%%%%%%%%%%%%%取整
- dst=zeros(m2,n2,q); %%%%%%%%%%%%%构造旋转后图像大小的空矩阵
- rx=ceil(m/2);ry=ceil(n/2); %%%%%%%%%%%%%%%原图像中心坐标
- rx1=ceil(m2/2);ry1=ceil(n2/2); %%%%%%%%%%%%旋转后图像中心坐标
- B=[cos(theta),-sin(theta);sin(theta),cos(theta)]; %%%%%%%%%%%%%%%%坐标映射矩阵
- %%%%%%%%%%%%%%%%历遍原图像里每一个点,计算对应的旋转后图像的坐标,并对目标图像赋值%%%%%%%%%%%%%%%%
- for i=1:m
- %%%%%%%%%%%%%%%%%%纵坐标距离中心的距离(可以负)
- for j=1:n
- x1=i-rx;
- y1=j-ry; %%%%%%%%%%%%%%%%%%横坐标距离中心的距离(可以负)
- D=[x1,y1]*B; %%%%%%%%%%%%%%%%%%%进行坐标变换
- y=ceil(D(2)+ry1)+1; %%%%%%%%%%%%%%%%%%%%算出新图像下坐标(加上中心坐标)
- x=ceil(D(1)+rx1)+1;
- for z=1:q
- dst(x,y,z)=src(i,j,z); %%%%%%%%%%%%%%%%%%%%RGB都赋值
- end
- end
- end
- dst=uint8(dst);
- figure(1);
- imshow(dst);
- %%%%%%%%%%%%%%插值%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- for i=2:m2-1
- for j=2:n2-1
- for z=1:3
- if(dst(i,j,z) == 0 && dst(i,j-1,z) ~= 0 && dst(i,j+1,z) ~= 0)
- dst(i,j,z) =dst(i,j-1,z) ;
- end
- end
- end
- end
- dst=uint8(dst);
- figure(2);
- imshow(dst);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%函数功能:以图像为远点右转函数,插值方法:双线性插值%%%%
%作者:张小胖话不多%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%时间:2013.9.26%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;close all; clc;
%%%%dst=my_img_rotate(I,theta)
src=imread('D:\Documents\Desktop\lenna.JPG'); %%%%读入原图像;
theta=pi/6;
[m,n,q]=size(src) %%%%%计算原图像的大小
A=[cos(theta),sin(theta);sin(theta),cos(theta)]; %%%%%%%%%%%计算图像旋转后大小的变换公式
C=[m,n]*A; %%%%%%%%%%%计算图像旋转后大小
m2=ceil(C(1))+1;n2=ceil(C(2))+1; %%%%%%%%%%%%%%取整
dst=zeros(m2,n2,q); %%%%%%%%%%%%%构造旋转后图像大小的空矩阵
rx=ceil(m/2);ry=ceil(n/2); %%%%%%%%%%%%%%%原图像中心坐标
rx1=ceil(m2/2);ry1=ceil(n2/2); %%%%%%%%%%%%旋转后图像中心坐标
B=[cos(theta),-sin(theta);sin(theta),cos(theta)]; %%%%%%%%%%%%%%%%坐标映射矩阵
%%%%%%%%%%%%%%%%历遍原图像里每一个点,计算对应的旋转后图像的坐标,并对目标图像赋值%%%%%%%%%%%%%%%%
for i=1:m
%%%%%%%%%%%%%%%%%%纵坐标距离中心的距离(可以负)
for j=1:n
x1=i-rx;
y1=j-ry; %%%%%%%%%%%%%%%%%%横坐标距离中心的距离(可以负)
D=[x1,y1]*B; %%%%%%%%%%%%%%%%%%%进行坐标变换
y=ceil(D(2)+ry1)+1; %%%%%%%%%%%%%%%%%%%%算出新图像下坐标(加上中心坐标)
x=ceil(D(1)+rx1)+1;
for z=1:q
dst(x,y,z)=src(i,j,z); %%%%%%%%%%%%%%%%%%%%RGB都赋值
end
end
end
dst=uint8(dst);
figure(1);
imshow(dst);
%%%%%%%%%%%%%%插值%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=2:m2-1
for j=2:n2-1
for z=1:3
if(dst(i,j,z) == 0 && dst(i,j-1,z) ~= 0 && dst(i,j+1,z) ~= 0)
dst(i,j,z) =dst(i,j-1,z) ;
end
end
end
end
dst=uint8(dst);
figure(2);
imshow(dst);
-
顶
- 0
-
踩
- 0