經過圖像變換后,一方面能夠更有效地反映圖像自身的特征,另一方面也可使能量集中在少量數據上,更有利於圖像的存儲、傳輸和處理。
從檢測器獲取投影數據的過程,就是圖像中的Radon變換。
8.1.1 Radon正變換

1 %對圖像進行0°和45°方向上的Radon變換 2 clear all; close all; 3 I=zeros(200, 200); %建立圖像 4 I(50:150, 50:150)=1; 5 [R, xp]=radon(I, [0, 45]); %Radon變換 6 figure; 7 subplot(131);imshow(I); 8 subplot(132);plot(xp, R(:, 1)); %0° Radon變換結果 9 subplot(133);plot(xp, R(:, 2)); %45° Radon變換結果 10 11 %對圖像從0°到180°每隔10°做Radon變換 12 clear all; close all; 13 I=zeros(200, 200); 14 I(50:150, 50:150)=1; 15 theta=0:10:180; %角度值 16 [R, xp]=radon(I, theta); %Radon變換 17 figure; 18 subplot(121);imshow(I); 19 subplot(122);imagesc(theta, xp, R); %繪制各個角度變換結果 20 colormap(hot); %設置調色板 21 colorbar; %添加顏色條 22 23 %Radon變換檢測直線 24 clear all; close all; 25 I=fitsread('solarspectra.fts'); 26 J=mat2gray(I); %轉換為灰度圖像 27 BW=edge(J); %獲取邊緣 28 figure;subplot(121);imshow(J); 29 subplot(122);imshow(BW); 30 theta=0:179; %角度 31 [R, xp]=radon(BW, theta); %Radon變換 32 figure;imagesc(theta, xp, R); %繪制各個角度變換結果 33 colormap(hot); %設置調色板 34 colorbar; %添加顏色條 35 Rmax=max(max(R)) %獲取最大值 36 [row, column]=find(R>=Rmax) %獲取行和列值 37 x=xp(row) %獲取位置 38 angel=theta(column) %獲取角度
1 %Radon反變換恢復圖像 2 clear all; close all; 3 I=imread('circuit.tif'); 4 theta=0:2:179; 5 [R, xp]=radon(I, theta); %Radon變換 6 J=iradon(R, theta); %Radon反變換 7 figure; 8 subplot(131);imshow(uint8(I)); 9 subplot(132);imagesc(theta, xp, R); 10 axis normal; 11 subplot(133);imshow(uint8(J));
iradon()函數利用R矩陣各列的投影來構造圖像I的近似值。投影數越多,重建后的圖像越接近原始的圖像。為了獲取准確的圖像,盡量使用較多的投影值。
1 %投影角度的多少對Radon變換和Radon反變換的影響 2 clear all; close all; 3 I=phantom(256); %讀入圖像 4 figure; 5 imshow(I); 6 theta1=0:10:170; 7 theta2=0:5:175; 8 theta3=0:2:178; 9 [R1, xp]=radon(I, theta1); 10 [R2, xp]=radon(I, theta2); 11 [R3, xp]=radon(I, theta3); 12 figure; 13 imagesc(theta3, xp, R3); 14 colormap hot; 15 colorbar; 16 J1=iradon(R1, 10); 17 J2=iradon(R2, 5); 18 J3=iradon(R3, 2); 19 figure; 20 subplot(131);imshow(J1); 21 subplot(132);imshow(J2); 22 subplot(133);imshow(J3);
8.2 圖像傅里葉變換
數學意義:將一個圖像轉換為一系列周期函數來處理
物理意義:傅里葉變換將圖像從空間域轉換到頻率域,逆變換將圖像從頻率域轉換到空間域
實際上對圖像進行二維傅里葉變換得到頻譜圖,就是圖像梯度的分布圖。頻譜圖上看到的明暗不一的亮點,對應圖像上某一點與鄰域點差異的強弱,即梯度大小。如果頻譜圖中暗點數多,實際圖像比較柔和,反之,如果頻譜圖中亮點多,那么實際圖像一定是尖銳的,邊界分明且邊界兩邊像素差異較大。
8.2.1 傅里葉變換的定義與性質
一維連續傅里葉變換:


離散傅里葉變換:


二維離散傅里葉變換的性質


1 %矩陣的二維離散傅里葉變換 2 clear all; close all; 3 I1=ones(4) %建立矩陣 4 I2=[2 2 2 2;1 1 1 1; 3 3 0 0; 0 0 0 0] 5 J1=fft2(I1) %傅里葉變換 6 J2=fft2(I2) 7 8 %圖像的二維離散傅里葉變換 9 clear all; close all; 10 I=imread('cameraman.tif'); %讀入圖像 11 J=fft2(I); %傅里葉變換 12 K=abs(J/256); 13 figure; 14 subplot(121);imshow(I); 15 subplot(122);imshow(uint8(K));

1 %通過函數ffthsift()進行平移 2 clear all; close all; 3 N=0:4 4 X=fftshift(N) %平移 5 Y=fftshift(fftshift(N)) %再平移 6 Z=ifftshift(fftshift(N)) %反平移 7 8 %圖像進行傅里葉變換和平移 9 %圖像的能量主要集中在低頻 10 clear all; close all; 11 I=imread('peppers.png'); 12 J=rgb2gray(I); 13 K=fft2(J); %傅里葉變換 14 K=fftshift(K); %平移 15 L=abs(K/256); 16 figure; 17 subplot(121);imshow(J); 18 subplot(122);imshow(uint8(L)); 19 20 %圖像變亮后進行傅里葉變換 21 %中央低頻部分變大了,頻譜圖的中央低頻部分代表了灰度圖像的平均亮度 22 clear all; close all; 23 I=imread('peppers.png'); 24 J=rgb2gray(I); 25 J=J*exp(1); %變亮 26 J(find(J>255))=255; 27 K=fft2(J); 28 K=fftshift(K); 29 L=abs(K/256); 30 figure; 31 subplot(121);imshow(J); 32 subplot(122);imshow(uint8(L)); 33 34 %圖像旋轉后進行傅里葉變換 35 clear all; close all; 36 I=imread('peppers.png'); 37 J=rgb2gray(I); 38 J=imrotate(J,45,'bilinear'); %圖像旋轉 39 K=fft2(J); %傅里葉變換 40 K=fftshift(K); %旋轉 41 L=abs(K/256); 42 figure; 43 subplot(121);imshow(J); 44 subplot(122);imshow(uint8(L)); 45 46 %圖像中添加高斯噪聲后進行傅里葉變換 47 clear all; close all; 48 I=imread('peppers.png'); 49 J=rgb2gray(I); 50 J=imnoise(J, 'gaussian', 0, 0.01); 51 K=fft2(J); 52 K=fftshift(K); 53 L=abs(K/256); 54 figure; 55 subplot(121);imshow(J); 56 subplot(122);imshow(uint8(L));

1 %灰度圖像的傅里葉變換和反變換 2 clear all; close all; 3 I=imread('onion.png'); 4 J=rgb2gray(I); 5 K=fft2(J); %傅里葉變換 6 L=fftshift(K); %平移 7 M=ifft2(K); %傅里葉反變換 8 figure; 9 subplot(121);imshow(uint8(abs(L)/198)); %顯示頻譜圖 10 subplot(122);imshow(uint8(M)); %顯示反變換得到的圖像 11 12 %灰度圖像的復制譜和相位譜 13 clear all; close all; 14 I=imread('peppers.png'); 15 J=rgb2gray(I); 16 K=fft2(J); 17 L=fftshift(K); 18 fftr=real(L); 19 ffti=imag(L); 20 A=sqrt(fftr.^2+ffti.^2); %幅度譜 21 A=(A-min(min(A)))/(max(max(A))-min(min(A)))*255; %歸一化到0-255 22 B=angle(K); %相位譜 23 figure; 24 subplot(121);imshow(A); %顯示幅度譜 25 subplot(122);imshow(real(B)); %顯示相位譜 26 27 %編程實現二維離散傅里葉變換 28 clear all; close all; 29 I=imread('onion.png'); 30 J=rgb2gray(I); 31 J=double(J); 32 s=size(J); 33 M=s(1); N=s(2); %獲取圖像的行數和列數 34 for u=0:M-1 35 for v=0:N-1 36 k=0; 37 for x=0:M-1 38 for y=0:N-1 39 k=J(x+1, y+1)*exp(-j*2*pi*(u*x/M+v*y/N))+k; %二維離散傅里葉變換公式 40 end 41 end 42 F(u+1, v+1)=k; %傅里葉變換結果 43 end 44 end 45 K=fft2(J); %采用了快速傅里葉變換算法,運算速度較快 46 figure; 47 subplot(121);imshow(K);%顯示結果 48 subplot(122);imshow(F);
1 %傅里葉變換識別圖像中的字符 2 clear all; close all; 3 I=imread('text.png'); %讀入圖像 4 a=I(32:45, 88:98); %模板 5 figure;imshow(I); %顯示原圖像 6 figure;imshow(a); %顯示模板 7 c=real(ifft2(fft2(I).*fft2(rot90(a, 2), 256, 256))); %傅里葉變換 8 figure;imshow(c, []); 顯示卷積后的結果 9 max(c(:)) %取最大值 10 thresh=60; %設置閾值 11 figure;imshow(c>thresh) %顯示識別結果
巴特沃斯濾波器

1 %對圖像進行巴特沃斯低通濾波 2 clear all; close all; 3 I=imread('cameraman.tif'); 4 I=im2double(I); 5 J=fftshift(fft2(I)); %傅里葉變換與平移 6 [x, y]=meshgrid(-128:127, -128:127); %產生離散數據 7 z=sqrt(x.^2+y.^2); 8 D1=10; D2=30; %濾波器的截至頻率 9 n=6; %濾波器的階數 10 H1=1./(1+(z/D1).^(2*n)); %濾波器 11 H2=1./(1+(z/D2).^(2*n)); %濾波器 12 K1=J.*H1; %濾波 13 K2=J.*H2; %濾波 14 L1=ifft2(ifftshift(K1)); %傅里葉反變換 15 L2=ifft2(ifftshift(K2)); %傅里葉反變換 16 figure; 17 subplot(131);imshow(I); %原圖像 18 subplot(132);imshow(real(L1)); %結果圖像 19 subplot(133);imshow(real(L2)); %截止頻率月底,圖像變得越模糊 20 21 %對圖像進行巴特沃斯高通濾波 22 clear all; close all; 23 I=imread('cameraman.tif'); 24 I=im2double(I); 25 J=fftshift(fft2(I)); 26 [x, y]=meshgrid(-128:127, -128:127); 27 z=sqrt(x.^2+y.^2); 28 D1=10; D2=40; %截止頻率 29 n1=4; n2=8; %濾波器階數 30 H1=1./(1+(D1./z).^(2*n1)); 31 H2=1./(1+(D2./z).^(2*n2)); 32 K1=J.*H1; %濾波 33 K2=J.*H2; 34 L1=ifft2(ifftshift(K1)); %傅里葉反變換 35 L2=ifft2(ifftshift(K2)); 36 figure; 37 subplot(131);imshow(I); 38 subplot(132);imshow(real(L1)); 39 subplot(133);imshow(real(L2)); %高通濾波保持了圖像的邊緣信息


1 %對圖像進行二維離散余弦變換 2 clear all; close all; 3 I=imread('coins.png'); 4 I=im2double(I); 5 J=dct2(I); %二維離散余弦變換 6 figure; 7 subplot(121);imshow(I); 8 subplot(122);imshow(log(abs(J)), []); %顯示變換系數,系數中的能量主要集中在左上角,其余大部分系數接近0

1 %dctmtx()生成離散余弦變換矩陣 2 clear all; close all; 3 A=[1 1 1 1; 2 2 2 2; 3 3 3 3] %建立矩陣 4 s=size(A); 5 M=s(1); %矩陣的行數 6 N=s(2); %矩陣的列數 7 P=dctmtx(M) %離散余弦變換矩陣 8 Q=dctmtx(N) %離散余弦變換矩陣 9 B=P*A*Q' %離散余弦變換 10 11 %利用dctmtx()進行圖像的離散余弦變換 12 clear all; close all; 13 I=imread('cameraman.tif'); 14 I=im2double(I); 15 s=size(I); 16 M=s(1); 17 N=s(2); 18 P=dctmtx(M); 19 Q=dctmtx(N); 20 J=P*I*Q'; %離散余弦變換 21 K=dct2(I); %離散余弦變換 22 E=J-K; %變換系數之差 23 find(abs(E)>0.000001) %查找系數差大於0.000001 24 figure; 25 subplot(121);imshow(J); %顯示離散余弦系數 26 subplot(122);imshow(K); %顯示離散余弦系數

1 %圖像的二維離散余弦反變換 2 clear all; close all; 3 I=imread('cameraman.tif'); 4 I=im2double(I); 5 J=dct2(I); %二維離散余弦變換 6 J(abs(J)<0.1)=0; %絕對值小於0.1的系數設置為0 7 K=idct2(J); %二維離散余弦反變換 8 figure; 9 subplot(131);imshow(I); %顯示原圖像 10 subplot(132);imshow(J); %變換系數 11 subplot(133);imshow(K); %顯示結果圖像
1 %通過函數blkproc()對圖像進行塊操作 2 clear all; close all; 3 I=imread('cameraman.tif'); 4 fun1=@dct2; %函數句柄 5 J1=blkproc(I, [8 8], fun1); %塊操作 6 fun2=@(x) std2(x)*ones(size(x)); %函數句柄 7 J2=blkproc(I, [8 8], fun2); %塊操作 8 figure; 9 subplot(121);imagesc(J1); 10 subplot(122);imagesc(J2); 11 colormap gray; %設置調色板


1 %通過離散余弦變換進行圖像壓縮 2 clear all; close all; 3 I=imread('rice.png'); %讀入圖像 4 J=im2double(I); 5 T=dctmtx(8); %計算離散余弦變換矩陣 6 K=blkproc(J, [8 8], 'P1*x*P2', T, T'); %對每個小方塊進行離散余弦變換 7 mask=[ 1 1 1 1 0 0 0 0 8 1 1 1 0 0 0 0 0 9 1 1 0 0 0 0 0 0 10 1 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 12 0 0 0 0 0 0 0 0 13 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 ]; 15 K2=blkproc(K, [8 8], 'P1.*x', mask); %系數選擇 16 L=blkproc(K2, [8 8], 'P1*x*P2', T', T); %對每個小方塊進行離散余弦反變換 17 figure; 18 subplot(121);imshow(J); 19 subplot(122);imshow(L);

8.4 其他圖像變換
8.4.1 Hadamard變換


1 %通過函數hadamard()產生Hadamard變換矩陣 2 clear all; close all; 3 H1=hadamard(2) %產生2階Hadamard變換矩陣 4 H2=hadamard(4) %產生4階Hadamard變換矩陣 5 H3=H2'*H2 6 7 %對圖像進行Hadamard變換 8 clear all; close all; 9 I=imread('peppers.png'); %讀入rgb圖像 10 I=rgb2gray(I); %轉換為灰度圖像 11 I=im2double(I); 12 h1=size(I, 1); %行 13 h2=size(I, 2); %列 14 H1=hadamard(h1); %Hadamard變換矩陣 15 H2=hadamard(h2); %Hadamard變換矩陣 16 J=H1*I*H2/sqrt(h1*h2); %Hadamard變換 17 figure; 18 set(0,'defaultFigurePosition',[100,100,1000,500]); 19 set(0,'defaultFigureColor',[1 1 1]) 20 subplot(121);imshow(I); %原圖像 21 subplot(122);imshow(J); %Hadamard變換結果
1 %對圖像進行Hough變換 2 clear all; close all; 3 I=imread('circuit.tif'); 4 I=im2double(I); 5 BW=edge(I, 'canny'); %邊緣檢測 6 [H, Theta, Rho]=hough(BW, 'RhoResolution', 0.5, 'ThetaResolution', 0.5); %Hough變換 7 figure; 8 set(0,'defaultFigurePosition',[100,100,1000,500]); 9 set(0,'defaultFigureColor',[1 1 1]) 10 subplot(121);imshow(BW); 11 subplot(122);imshow(imadjust(mat2gray(H))); 12 axis normal; %設置坐標軸 13 hold on; 14 colormap hot; %設置調色板

1 %通過圖像的Hough變換檢測直線 2 clear all; close all; 3 I=imread('gantrycrane.png'); 4 I=rgb2gray(I); 5 BW=edge(I, 'canny'); %獲取圖像邊緣 6 [H, Theta, Rho]=hough(BW, 'RhoResolution', 0.5, 'Theta', -90:0.5:89.5);%Hough變換 7 P=houghpeaks(H, 5, 'threshold', ceil(0.3*max(H(:)))); %獲取5個最值點 8 x=Theta(P(:, 2)); %橫坐標 9 y=Rho(P(:, 1)); %縱坐標 10 figure; 11 set(0,'defaultFigurePosition',[100,100,1000,500]); 12 set(0,'defaultFigureColor',[1 1 1]) 13 subplot(121); 14 imshow(imadjust(mat2gray(H)), 'XData', Theta, 'YData', Rho,... 15 'InitialMagnification', 'fit'); %繪制Hough變換結果 16 axis on; %設置坐標軸 17 axis normal; 18 hold on; 19 plot(x, y, 's', 'color', 'white'); 20 lines=houghlines(BW, Theta, Rho, P, 'FillGap', 5, 'MinLength', 7); %檢測直線 21 subplot(122);imshow(I); 22 hold on; 23 maxlen=0; 24 for k=1:length(lines) %繪制多條直線 25 xy=[lines(k).point1; lines(k).point2]; 26 plot(xy(:,1), xy(:, 2), 'linewidth', 2, 'color', 'green'); 27 plot(xy(1,1), xy(1, 2), 'linewidth', 2, 'color', 'yellow'); 28 plot(xy(2,1), xy(2, 2), 'linewidth', 2, 'color', 'red'); 29 len=norm(lines(k).point1-lines(k).point2); 30 if (len>maxlen) %獲取最長直線坐標 31 maxlen=len; 32 xylong=xy; 33 end 34 end 35 hold on; 36 plot(xylong(:, 1), xylong(:, 2), 'color', 'blue'); %繪制最長的直線






