圖像的幾何運(yùn)算
原圖:
讀取原圖(這里我的圖片名字是atm.png):
% 先讀入圖像
I = imread('atm.png');
% imshow(I);
1. 旋轉(zhuǎn) (imrotate)
我們先說原理,圖像旋轉(zhuǎn)的本質(zhì)是向量的旋轉(zhuǎn)。
矩陣乘法的實(shí)質(zhì)是進(jìn)行線性變換,因此對(duì)一個(gè)向量進(jìn)行旋轉(zhuǎn)操作也可以通過矩陣和向量相乘的方式進(jìn)行。
因?yàn)閳D像都是通過二維矩陣存放的(單通道),所以對(duì)圖像進(jìn)行旋轉(zhuǎn)時(shí)要先設(shè)定一個(gè)像素作為旋轉(zhuǎn)軸,然后其他的像素位置可以看作從旋轉(zhuǎn)軸出發(fā)的向量。
假設(shè)有二維向量
v
=
[
x
;
y
]
v = [x ; y]
v=[x;y] ,若要進(jìn)行逆時(shí)針旋轉(zhuǎn)角度
a
a
a 。則旋轉(zhuǎn)矩陣R為
[
c
o
s
(
a
)
?
s
i
n
(
a
)
s
i
n
(
a
)
c
o
s
(
a
)
]
\begin{bmatrix} cos(a)& -sin(a)\\ sin(a) & cos(a) \end{bmatrix}
[cos(a)sin(a)??sin(a)cos(a)?]旋轉(zhuǎn)后的向量
v
2
=
R
?
v
v2 = R * v
v2=R?v 。在正式處理過程中可以這么表示,原像素位置記為
p
p
p ,中心點(diǎn)記為
c
c
c ,旋轉(zhuǎn)后像素位置記為
p
p
pp
pp ,
則有
(
p
p
?
c
)
=
R
?
(
p
?
c
)
(pp - c) = R*(p - c)
(pp?c)=R?(p?c) 。
如果通過原圖的點(diǎn)來計(jì)算新圖的點(diǎn),那么新圖的點(diǎn)可能會(huì)出現(xiàn)漏算的。
這里我們進(jìn)行逆向求點(diǎn),通過新圖的點(diǎn),來找舊圖的點(diǎn),這樣就不會(huì)漏算了。
這里我設(shè)函數(shù)名為imrotate_test.m
% 進(jìn)行旋轉(zhuǎn)
% I是圖像,angle是角度
function J = imrotate_test(I,angle)
% 首先獲得高和寬,色彩的層數(shù)
[height, width, color] = size(I);
angle = angle/180*pi;
R=[cos(angle),-sin(angle);sin(angle),cos(angle)];%旋轉(zhuǎn)矩陣
R=R';%求出旋轉(zhuǎn)矩陣的逆矩陣
c1=[height;width]/2;%原圖中心
%計(jì)算顯示完整圖像需要的畫布大小
height2=floor(width*sin(angle)+height*cos(angle))+1;
width2=floor(width*cos(angle)+height*sin(angle))+1;
c2=[height2,width2]/2;%求新畫布中點(diǎn)
%初始化目標(biāo)畫布
J=uint8(ones(height2,width2,3)*128);
for k = 1:color
for i = 1:height2
for j = 1:width2
p=[i;j];%遍歷新圖像像素點(diǎn)
pp=round(R*(p-c2)+c1);%計(jì)算在原來圖像中的位置
%逆向進(jìn)行像素查找
if(pp(1)>=1&&pp(1)<=height&&pp(2)>=1&&pp(2)<=width)
J(i,j,k)=I(pp(1),pp(2),k);
end
end
end
end
%顯示圖像
figure;
imshow(J);
代碼:
% 自帶的函數(shù)
% J1 = imrotate(I,45);
J1 = imrotate_test(I,45); % 進(jìn)行旋轉(zhuǎn)
運(yùn)行結(jié)果:
2. 縮放(imresize)
這個(gè)很好理解就不解釋了。
這里我用到逆向求點(diǎn),通過新圖找舊圖的點(diǎn)
這里我設(shè)函數(shù)名為imresize_test.m
% 進(jìn)行放大縮小
% I:圖像 ,r:比例
function J = imresize_test(I,r)
% 首先獲得高和寬,色彩的層數(shù)
[height, width, color] = size(I);
% 新的圖層
height2=floor(height*r)+1;
width2=floor(width*r)+1;
%初始化目標(biāo)畫布
J=uint8(ones(height2,width2,3)*128);
for k = 1:color
for i = 1:height2
for j = 1:width2
p=[i;j];%遍歷舊圖像像素點(diǎn)
pp=round(p/r);%計(jì)算在原來圖像中的位置
%這里仍然使用round函數(shù),但結(jié)果會(huì)比方案一好得多
%逆向進(jìn)行像素查找
if(pp(1)>=1&&pp(1)<=height&&pp(2)>=1&&pp(2)<=width)
J(i,j,k)=I(pp(1),pp(2),k);
end
end
end
end
%顯示圖像
figure;
imshow(J);
代碼:
% 自帶函數(shù)
% J2 = imresize(I,1/3);
J2 = imresize_test(I,1/3);
運(yùn)行結(jié)果:
3. 裁剪 (imcrop)
直接求點(diǎn),直接上代碼!??!(參數(shù)與自帶的函數(shù)不同)
這里我設(shè)函數(shù)名為imcrop_test.m
% 進(jìn)行裁剪
% w:水平方向的兩個(gè)值,h:豎直方向的兩個(gè)值
function J = imcrop_test(I,w,h)
% 首先獲得高和寬,色彩的層數(shù)
[height, width, color] = size(I);
if w(1)>w(2)
a = w(2);
w(2) = w(1);
w(1) = a;
end
if h(1)>h(2)
a = h(2);
h(2) = h(1);
h(1) = a;
end
if w(2)>width||h(2)>height||w(1)<=0||h(1)<=0
return
end
% 新的圖層
height2=h(2)-h(1);
width2=w(2)-w(1);
%初始化目標(biāo)畫布
J=uint8(ones(height2,width2,3)*128);
for k = 1:color
for i = 1:height2
for j = 1:width2
pp=[i+h(1);j+w(1)];
J(i,j,k)=I(pp(1),pp(2),k);
end
end
end
%顯示圖像
figure;
imshow(J);
代碼:
% 自帶函數(shù)
% J3 = imcrop(I,[95,80,300,300]); % 略有不同,參數(shù):[左上角坐標(biāo),兩個(gè)截取長度]
J3 = imcrop_test(I,[95,398],[80,379]);
運(yùn)行結(jié)果:
4. 鏡像變換(flip,flipdim也可以)
水平變換,就是左右點(diǎn)關(guān)于中線交換
這里我設(shè)函數(shù)名為flip_test.m
% I是圖像
% a是選擇的變化 1是水平變換 2是垂直變換 3是對(duì)角變換
function J = flip_test(I,a)
% 首先獲得高和寬,色彩的層數(shù)
[height, width, color] = size(I);
%初始化目標(biāo)畫布
J=uint8(ones(height,width,color)*128);
if a==1 % 水平
for k = 1:color
for i = 1:height
for j = 1:width
pp=round(p/r);%計(jì)算在原來圖像中的位置
%這里仍然使用round函數(shù),但結(jié)果會(huì)比方案一好得多
%逆向進(jìn)行像素查找
if(pp(1)>=1&&pp(1)<=height&&pp(2)>=1&&pp(2)<=width)
J(i,j,k)=I(pp(1),pp(2),k);
end
end
end
end
elseif a==2 % 垂直
for k = 1:color
for i = 1:height
for j = 1:width
p=[i;j];%遍歷新圖像像素點(diǎn)
J(height-i+1,j,k)=I(p(1),p(2),k);
end
end
end
elseif a==3 % 對(duì)角
for k = 1:color
for i = 1:height
for j = 1:width
p=[i;j];%遍歷新圖像像素點(diǎn)
J(height-i+1,width-j+1,k)=I(p(1),p(2),k);
end
end
end
else
disp('你的輸入錯(cuò)誤');
return
end
%顯示圖像
figure;
imshow(J);
end
代碼:
% 自帶的函數(shù)
% J4 = flip(I,1);% 水平變換
% J5 = flip(I,2);% 垂直變換
% 對(duì)角變換我沒有找到,但是直接變換兩次不就是對(duì)角變換了嘛
J4 = flip_test(I,1);
title('水平變換');
J5 = flip_test(I,2);
title('垂直變換');
J6 = flip_test(I,3);
title('對(duì)角變換');
運(yùn)行結(jié)果:
5. 平移
這里我設(shè)函數(shù)名為translation_test.m
% I為處理圖像,x是一個(gè)數(shù)組,第一個(gè)數(shù)為右移的長度,第二個(gè)為下移的長度
function J = translation_test(I,x)
% 首先獲得高和寬,色彩的層數(shù)
[height, width, color] = size(I);
%初始化目標(biāo)畫布
J=uint8(ones(height,width,color)*128);
for k = 1:color
for i = 1:height
for j = 1:width
p=[i;j];%遍歷舊圖像像素點(diǎn)
pp=[i-x(1);j-x(2)]; %計(jì)算在原來圖像中的位置
%這里仍然使用round函數(shù),但結(jié)果會(huì)比方案一好得多
%逆向進(jìn)行像素查找
if(pp(1)>=1&&pp(1)<=height&&pp(2)>=1&&pp(2)<=width)
J(i,j,k)=I(pp(1),pp(2),k);
end
end
end
end
%顯示圖像
figure;
imshow(J);
代碼:
% 通過一些自帶的函數(shù),可以實(shí)現(xiàn)平移
%translate(SE, [y x])在結(jié)構(gòu)元素SE上進(jìn)行y和x方向的位移 正數(shù)對(duì)應(yīng)右移和下移
% se = translate(strel(1),[100 80]);
% J7 = imdilate(I,se);%利用膨脹函數(shù)平移圖像
J7 = translation_test(I,[-50,-100]);
運(yùn)行結(jié)果:
文章來源:http://www.zghlxwxcb.cn/news/detail-465366.html
創(chuàng)作不易,如果對(duì)你有幫助,求求你給我個(gè)贊!??!
點(diǎn)贊 + 收藏 + 關(guān)注?。?!
如有錯(cuò)誤與建議,望告知?。。。▽⒂谙缕恼赂?br> 請(qǐng)多多關(guān)注我?。?!謝謝!?。?/strong>文章來源地址http://www.zghlxwxcb.cn/news/detail-465366.html
到了這里,關(guān)于數(shù)字圖像處理 matlab圖像的幾何運(yùn)算 實(shí)驗(yàn)三 旋轉(zhuǎn) 縮放 裁剪 鏡像變換 平移的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!