1. 程式人生 > >影象的灰度變換——影象旋轉 影象的反色處理 對比度拉伸

影象的灰度變換——影象旋轉 影象的反色處理 對比度拉伸

               

這次我們要處理的是對影象進行旋轉操作,具體要求,如下:

       自定義一個影象的仿射變換函式,用於旋轉給定的輸入影象,該函式的輸入引數包括處理前的影象和旋轉角度。輸入的角度為正數,表明處理結果為順時針旋轉,負數則為逆時針旋轉,輸出引數為處理後的影象。

       曾參考《數字影象處理(第三版)》一書中P51的公式編寫過自己的影象“旋轉”函式,但是在某些角度下,輸出結果卻發生了錯誤,至於原因,也由於時間關係,仍未思考出來。使用Matlab程式設計,原始碼如下:

%自己寫的函式function []=myRotation(pho,angle)im1=imread(pho);subplot(121);imshow(im1);title('輸入影象');im1=double(im1);[r,c,h]=size(im1); R=angle*pi/180;h2 = ceil(r*cos(R)+c*sin(R));w2 = ceil(r*sin(R)+c*cos(R));im2=zeros(h2,w2,h); T=[sin(R) cos(R); cos(R) -sin(R)];%invT=inv(T);for i=1:h    for x=1:h2        for y=1:w2            temp=([x y]-[0 r*sin(R)])/T;            temp(1)=ceil(temp(1));            temp(2)=ceil(temp(2));            if temp(2)>0 && temp(2)<=r && temp(1)>0 && temp(1)<=c                im2(x,y,i)=im1(temp(2),temp(1),i);            end        end    endendsubplot(122);imshow(uint8(im2));title('輸出影象');

       另外,採用了一種方法(參考 點選開啟連結),同樣使用推匯出來的公式,採用反向對映的方法,結合雙線性內插,得出旋轉後的影象。但是得出來的結果,如輸入 180°,沒有出現輸出結果。參考後修改的程式如下:

function []=myRotation3(pho,angle)im1=imread(pho);im1=double(im1);[m,n,h]=size(im1); R = angle*pi/180;   %旋轉角度%新影象大小m2 = ceil(m*cos(R)+n*sin(R));n2 = ceil(m*sin(R)+n*cos(R)); u0= m*sin(R);%平移量 %變換矩陣   T=[cos(R),sin(R);-sin(R),cos(R)];L = zeros(m2,n2);for i=1:h    for u=1:n2      for v=1:m2        %新影象座標變換到原影象座標x和y中        temp = T*([u;v]-[u0;0]);        x= temp(1);        y= temp(2);        if x>=1 & x<=m & y>=1 & y<=n    %若變換出的x和y在原影象範圍內            x_low=floor(x);            x_up=ceil(x);            y_low=floor(y);            y_up=ceil(y);    %雙線性內插值            p1=im1(x_low,y_low,i);            p2=im1(x_up,y_low,i);            p3=im1(x_low,y_low,i);            p4=im1(x_up,y_up,i);            s=x-x_low;            t=y-y_low;            L(u,v,i)=(1-s)*(1-t)*p1+(1-s)*t*p3+(1-t)*s*p2+s*t*p4;        end      end    endend imshow(uint8(L));title('輸出影象');

而正確程式程式碼,則是通過研究參考 影象旋轉演算法原理點選開啟連結),在只有原理的情況下,研究透,將其轉化為 程式。MATLAB程式碼如下:

%這個旋轉才沒有bugfunction []=myRotation(pho,angle)im1=imread(pho);subplot(121);imshow(im1);title('輸入影象');im1=double(im1);[r,c,h]=size(im1); %將角度單位化為弧度單位R=-angle*pi/180;%這樣的寬高會出現BUG,原因不明%h2 = ceil(r*cos(R)+c*sin(R));%w2 = ceil(r*sin(R)+c*cos(R)); %將對角線作為旋轉後圖像的寬高h2=ceil(sqrt(r*r+c*c));w2=h2; im2=zeros(h2,w2,h); %旋轉時x y的偏移量dx=-0.5*w2*cos(R)-0.5*h2*sin(R)+0.5*c;dy=0.5*w2*sin(R)-0.5*h2*cos(R)+0.5*r; %採用反向對映for i=1:h    for x=1:h2        for y=1:w2            %由結果影象的座標 得出 原來影象的座標            x0=ceil(x*cos(R)+y*sin(R)+dx);             y0=ceil(-x*sin(R)+y*cos(R)+dy);                        if x0>0 && x0<=r && y0>0 && y0<=c                im2(x,y,i)=im1(x0,y0,i);            end        end    endend%顯示影象subplot(122);imshow(uint8(im2));title('輸出影象');

旋轉45°——> myRotation('實驗2_lena.bmp',45),結果如下:


旋轉-45°——> myRotation('實驗2_lena.bmp',-45),結果如下:

影象反色處理

       自定義一個函式,將輸入影象進行反色處理,該函式輸入引數為處理前的影象,輸出引數為處理後的影象。

Matlab程式設計,程式碼如下:

function []=myFanse(pho)im1 = imread(pho);subplot(121);imshow(im1);title('輸入影象');im1 = double(im1);[r c m] = size(im1);im2 = zeros(r,c,m);for i=1:mfor j=1:rfor k=1:cim2(j,k,i)=255-im1(j,k,i); %由最高灰度級減去原座標位置的灰度級進行反色endendendim2 = uint8(im2);subplot(122);imshow(im2);title('輸出影象');
       當然,其實也可以利用Matlab中的矩陣運算編寫程式,這樣程式可以更加精簡,這裡就不給出了。   

       myFase('實驗2_lena.bmp'),執行結果如下:


影象對比度拉伸變換

  自定義一個影象的對比度拉伸函式,將輸入影象的對比度拉伸到指定的灰度級區間,該函式的輸入引數包括處理前的影象、期望灰度級區間的最小值和最大值(如指定區間為[50 200]),輸出引數為處理後的影象。

Matlab程式碼如下:

function []=myContrConver(pho, mi, ma)im1 = imread(pho);subplot(121);imshow(im1);title('輸入影象');im1 = double(im1);[r c m] = size(im1);im2 = zeros(r,c,m);%for i=1:m%    for j=1:r%        for k=1:c%            im2(j,k,i)=min+(im1(j,k,i)-minR)/(maxR-minR)*(max-min);%        end%    end%end %先對原影象的 灰度級 進行歸一化,再由歸一化的區間縮放至所需區間tempIma1=im1(:,:,1);tempIma2=im1(:,:,2);tempIma3=im1(:,:,3);im2(:,:,1)=mi+(im1(:,:,1)-min(tempIma1(:)))/(max(tempIma1(:))-min(tempIma1(:)))*(ma-mi);im2(:,:,2)=mi+(im1(:,:,2)-min(tempIma2(:)))/(max(tempIma2(:))-min(tempIma2(:)))*(ma-mi);im2(:,:,3)=mi+(im1(:,:,3)-min(tempIma3(:)))/(max(tempIma3(:))-min(tempIma3(:)))*(ma-mi); im2=uint8(im2);subplot(122);imshow(im2);title('輸出影象');

       myContrConver('實驗2_lena.bmp'),執行結果如下: