1. 程式人生 > >MATLAB影象處理_學習筆記

MATLAB影象處理_學習筆記

       由於工作需要,開始研究一下MATLAB影象處理相關的知識,影象處理只是matlab應用領域中小小的一部分而已。以前只是聽說過MATLAB很強大,但沒有系統的學過,如今開始學時,發現matlab確實很不錯、很高大上。操作起來很方便,特別是編寫程式時,比C語言更簡潔。

很多人都是大學裡就學過matlab的,由於是半路出家,所以知識不是很全面,直接拿了一本岡薩雷斯的MATLAB版的書就開始看,下面做一些簡單的小記錄。

1. matlab命令基礎:

基礎命令:

clc——清除視窗

clear——清除之前賦值過的變數
disp——列印資訊,相當於echo
celldisp——列印元胞陣列內容
who
——簡單的顯示當前已有變數
whos——顯示所有變數及詳細內容 whos也可以指定顯示某個變數
tan/sin/cos/log ——各種數學運算
...——用來續行
定義陣列——x=1:100
定義矩陣——A=[1,1,2] A=[1 2 2]; 加分號表示不顯示命令執行結果 定義空矩陣B=[]
矩陣轉置——A=[1 3 5 7]  B=A' 或 B=A.'可以把行向量轉換為列向量
取元素——A(1)取A中第一個元素  A(1:5)取A中第一到五的元素 
A(1:end)取第1到最後的元素,產生一個行向量; A(:)產生一個列向量
A(1:2:end)表示步長為2 步長也可以為負值 如A(end:-2:1)
linspace
——x=linspace(a,b,n)產生含有n個元素的行向量x n個元素線性隔開 幷包含a和b
:的活用——A=[1 2 3; 4 5 6; 7 8 9] A(:,3)取整個第三列  A(1:2, 1:3) 取兩行三列
+
-
*——* 表示矩陣與矩陣相乘,滿足線性代數上學的矩陣與矩陣的乘法,

   .*表示矩陣中元素與元素相乘,這兩個矩陣的維數必需相同。/和./也一樣的道理

length/size/numel的用法:

length(x) ——返回x的長度 如果x是單個變數 返回1 如果x是矩陣 返回該矩陣行數與列數中的較大者。

size(x)      ——當x是單個變數時,返回[1 1] 當x是矩陣是 返回矩陣的行數與列數 可以這樣來接受[m n]=size(x)

numel(x)  ——當x是單個變數時 返回1, 當x是矩陣時,返回矩陣元素總個數。

/

format compact——以緊湊方式顯示
format loose  ——以鬆散方式顯示


mean函式:

    >>如果有這樣一個矩陣:A = [1 2 3; 3 3 6; 4 6 8; 4 7 7];
         用mean(A)(預設dim=1)就會求每一列的均值
         ans =
 3.0000  4.5000  6.0000

    >>用mean(A,2)就會求每一行的均值 
    ans =
     2.0000
     4.0000
     6.0000
     6.0000

   >> mean(A(:)) 求總的平均值

其他函式:

zeros(M,N)——生成一個M*N的double型矩陣 元素均為0

ones(M,N)——生成一個M*N的double型矩陣 元素均為1

true(M,N)——生成一個M*N型的logical矩陣,元素均為1
false(M,N)——與上面的true相反
magic(M,N)——生成一個魔術幻陣
rand(M,N)——生成一個M*N的矩陣 元素大小在[0-1中均勻分佈]
randn(M,N)——生成一個M*N的矩陣 矩陣元素正態分佈 隨機數均值是0 方差是1.

plot(X,Y)——畫二維影象
subplot(m,n,p)——m代表生成影象的行數,n是列數,p代表子圖編號
plot3(X,Y,Z)——畫三維圖
mesh(X,Y,Z)——畫三維圖
surf(X,Y,Z)——畫三維圖,並上色

matlab函式設計:

.m檔案建立的函式檔案
function [A, B] = fun(A, B) //輸入A、B兩個變數,返回A、B兩個變數 一般.m檔名命名為函式名字

% xxxxxx 代表註釋,在命令視窗中輸入help fun可以顯示這個註釋

例項:

function [g,k,l] = two(x)
error(nargchk(1,1,nargin))
% error(nargchk(1,2,nargin))
if x<=1
    g = x;
end
g = 0;
k = nargin;
l = nargout;
for i=1:1:x
    g = g + i;
end

呼叫時寫tow(10),就可以計算1~10的和。

匿名函式:

var = @(x)(x+1)
呼叫時形如var(1)即可,@後面跟引數列表

接受使用者輸入資訊:
t = input('Enter you data:', 's');
t='12.6, x2y, z';
[a,b,c] = strread(t, '%f%q%q', 'delimiter', ',') //按指定的格式讀入a b c

matlab中,影象大致分為二值影象(0/1)、灰度影象(0-255灰度級)、RGB影象(R、G、B三個分量 三個分量都相同時,所表示的顏色就退化為灰度)、索引影象。
      灰度、亮度、強度通常是同一個概念。
      所有影象按照特性分為點陣圖和向量圖,點陣圖常見格式:JPG GIF BMP向量圖:PNG
      機器視覺又稱計算機視覺,試圖開發出一種模擬人眼的能力,能夠理解自然景物與環境的系統,比較高階哦。

nargin將返回輸入到函式的引數個數、nargout用於函式的輸出
nargchk用於檢查引數數目是否正確margchk(low, high, number),使用例項:
function G = test(X, Y)

error(nargchk(1,2,nargin));

2. 影象處理基礎:

imread——讀入影象A=imread('1.jpg')
imshow——顯示影象imshow(A, B);  imshow(A, [low high]);
                    會將所有小於或等於low的值顯示為黑色,大於或等於high的值顯示為白色
                  若B省略,預設的灰度級是256,imshow(A, [])  []表示將low設為A的最小值 將high設為A的最大值
                    顯示多幅影象:imshow(A), figure,imshow(B)
imwrite——儲存影象 imwrite(A, '2.jpg')
                     imwrite(A, '2.jpg', 'quality', q) // q在0-100之間(由於JPFG壓縮 q越小影象退化越嚴重)
size(A)——顯示影象的大小
imfinfo——顯示影象的詳細資訊 imfinfo 1.jpg 也可以K=imfinfo('1.jpg') 就可以使用K.Height K.Width等等資訊
                    學會計算影象的壓縮比:imgBytes=(K.Height*K.Width*K.BitDepth/8) compress_bytes=K.FileSize

                    imgBytes / compress_bytes ==壓縮比

                    命令視窗輸入:imfinfo test.jpg,顯示資訊如下:

ans = 

           Filename: 'C:\Documents and Settings\Administrator\My Documents\MATLAB\test.jpg'
        FileModDate: '30-Sep-2014 10:31:18'
           FileSize: 1609315
             Format: 'jpg'
      FormatVersion: ''
              Width: 2336
             Height: 1752
           BitDepth: 24
          ColorType: 'truecolor'
    FormatSignature: ''
    NumberOfSamples: 3
       CodingMethod: 'Huffman'
      CodingProcess: 'Sequential'
            Comment: {}

double/im2double/mat2gray的區別:

        A=imread('1.jpg');

        A(1,1,:)          ——顯示A中第1行第一列畫素點(包含紅、綠、藍)三個分量的值

        B=double(A)——轉換為double型別 值不會變 注意 使用im2double值會[0-1]
        im2double   ——若輸入是uint8型別 每個值會除以255. 
        mat2gray()   ——可以將double型別轉換為歸一化的double型別
        區別:

        im2double:如果輸入型別是uint8、unit16 、logical,則按照0-->>0,255-->>1,將其值按比例處理成0~1之間的double數值;如果輸入型別是double,輸出沒有處理;

        double:返回數值與輸入相同的double型別矩陣;

        mat2gray:對輸入進行歸一化處理,最小值-->>0;最大值-->>1,輸出型別為double。

        在實際的對影象處理過程中,由於我們讀入影象是unit8型,而在MATLAB的矩陣運算中要求所有的運算變數為double型(雙精度型)。因此通常使用im2double函式將影象資料轉換成雙精度型資料。

注意:uint8類、uint16類RGB影象取值範圍分別是[0, 255]、[0, 65535],而double類範圍是[0, 1]

C=[-1,0.5; 2,3] 
B=im2uint8(C)——im2uint8把所有大於1的值轉換為255 小於0 的值轉為0 其他值乘以255
im2bw          ——得到二值影象 可以先A=mat2gray(B), im2bw(A, 0.5)

IPT支援的影象的算術函式:

imadd——影象相加
imsubtract——影象相減
immultiply——影象相乘
imdivide          ——影象相除
imabsdiff——計算兩幅影象之間的絕對差
imcomplement——對影象求補
imlincomb——計算兩幅或多幅影象的線性組合

影象旋轉函式:

imrotate,matlab預設是逆時針旋轉, imrotate引數解釋

        angle顧名思義 就是你旋轉的角度, method 就是你實現旋轉用的是什麼方法,有三種  和後面的插值放大縮小是一下就是 最鄰近插值法 雙線性插值法 三次卷積插值法,英語表示就是  'nearest'    'bilinear'    'bicubic'。        不同的插值方法得到的旋轉影象有細微的差別 如果你不選在 matlab預設的是最鄰近插值法 那麼影象會有一定的失真,這個失真主要是因為matlab在計算每個點的新座標的時候得到的數值不是整數,要去整所造成的最後說說bbox   這個的意義主要分為2種,也就是說我們在這一項有2個選擇 一個是‘loose’ 另外一個是‘crop’

        loose  就是寬鬆的意思 顧名思義就是說 影象旋轉後 系統會給予一個寬鬆的環境去匹配它,這樣你得到的圖片就是一個完整的圖片 

        matlab的解釋是 When BBOX is 'loose', B

        includes the whole rotated image, which generally is larger than A.
        crop 就是剪下啦,也就是困擾了大家很久的問題,為什麼旋轉後圖像變小了,因為matlab預設的是crop  超過圖片原來大小的部分被crop了
>> subplot(2,2,1)
>> imshow(A)
>> subplot(2,2,2)
>> imshow(imrotate(A, 30, 'bilinear', 'loose'));
>> subplot(2,2,3)
>> imshow(imrotate(A, 30, 'bilinear', 'crop'));

3. 亮度變換與空間濾波:

1. 亮度
    imadjust函式
    A=imread('1.jpg');
    B= imadjust(A, [], [], 0.75); // gamma<1 變亮
    imshow(B)

    C=imadjust(A, [0 1], [1 0]);
    效果等價於C=imcomplement(A) 都是求影象的負片 
2. 對比度拉伸函式
     g = 1./(1+(m./(f+eps)).^E) // 加eps是為了防止溢位

3. 直方圖
    imhist函式:
    h = imhist(f, b) //b是灰度級個數 預設是256
    numel(f) //得到畫素點個數
    B=rgb2gray(A); subplot(121), imshow(B); subplot(122), imhist(B);
    直方圖均衡化:
    histeq函式:
    J=histeq(I)
例項:
>> A=imread('test.jpg');
>> B=rgb2gray(A);
>> imhist(B);//顯示直方圖
>> figure;
>> imhist(histeq(B)) //顯示均衡化後的直方圖
>> C=histeq(B);
>> imwrite(C, 'xxx.jpg');

影象如下所示:

 


4. 空間濾波:

    線性空間濾波:imfilter函式
    g=imfilter(f,w,filtering_mode, boundary_options, size_options); 
    //filtering_mode=corr/conv size_options=same/full
    通用語法為 g = imfilter(f, w, 'replicate');
    非線性濾波:colfilt函式

    IPT中的線性濾波器:
      fspecial函式用來生成濾波掩膜w
      w = fspecial('type', parm) //type表示濾波器型別
      type值可以是:average disk gaussian laplacian log motion prewitt sobel unsharp

例項:

使用拉普拉斯運算元來增強影象,包括銳化,同時應該保留其灰度色調

test_shape.m

function [] = test_sharp(A)
% Test Sharp
B= im2double(A);
w= fspecial('laplacian', 0);//laplacian時 第二個引數預設是0.5
C= imfilter(B, w, 'replicate');
D= B-C;
imwrite(D, 'out.jpg');
最後對比A與C的效果  發現影象明顯更為清晰了。。。
可以直接用unsharp選項,效果與上面的差不多
A=imread('test.jpg');
w = fspecial('unsharp')
B=im2double(A);
C=imfilter(B, w, 'replicate');
imwrite(C, 'out.jpg');

上面使用拉普拉斯運算元產生的w=[0 1 0; 1 -4 1; 0 1 0]; 中心為-4,現在我們手工指定中心為-8的情況如下:
function [] = test_sharp(A)
w4 = fspecial('laplacian', 0);
w8 = [1 1 1; 1 -8 1; 1 1 1];
A = im2double(A);
A4 = A - imfilter(A, w4, 'replicate');
A8 = A - imfilter(A, w8, 'replicate');
imwrite(A4, '4.jpg');
imwrite(A8, '8.jpg');

會發現影象銳化效果更好,影象更清晰。


    IPT中的非線性濾波器:
    ordfilt2函式  g = ordfilt2(f, order, domain)
    中值濾波medfilt2

    影象中加入噪聲:格式:J = imnoise(I, type, parm)

    >> A=imread('test.jpg');
    >> B = imnoise(A, 'salt & pepper', 0.02);
    >> C=rgb2gray(B);
    >> D=medfilt2(C, [3 3]);//中值濾波
    >> imwrite(D, 'xxx.jpg')



4. 彩色影象處理

>> A = imread("test.jpg");
%獲取影象R、G、B每個分量
>> R = A(:,:,1);
>> G = A(:,:,2);
>> B = A(:,:,3);
>> D = cat(3, R, G, B); //cat組合成影象

clear
rgb=imread('xxx.jpg');
rgb_r=rgb(:,:,1);
rgb_g=rgb(:,:,2);
rgb_b=rgb(:,:,3);
[x y z]=size(rgb);
zero=zeros(x, y);
R=cat(3,rgb_r,zero,zero);
G=cat(3,zero,rgb_g,zero);
B=cat(3,zero,zero,rgb_b);
RGB=cat(3,rgb_r,rgb_g,rgb_b);
subplot(2,2,1),imshow(R),title('紅色分量');
subplot(2,2,2),imshow(G),title('綠色分量');
subplot(2,2,3),imshow(B),title('藍色分量');
subplot(2,2,4),imshow(RGB);