1. 程式人生 > >Octave入門之一些常見的語法知識

Octave入門之一些常見的語法知識

最近準備開始做數字影象處理的實驗,我安裝了Octave,於是準備繼續用Octave做實驗,(Matlab你懂的,入門買個覺得有點浪費,況且Octave能用懂,轉到Matlab估計也不是很困難微笑)。


下面記錄下學習中覺得用的比較多的基本知識:

1、訪問矩陣的特定元素值

2、獲取矩陣的某一行或某一列

3、為矩陣加一列全為1的列

4、點運算

5、subplot

6、A=[m:gap:n]

7、A = [m<n]是什麼意思

8、Octave中的...是什麼意思

9、上邊8這個例子可能寫的比較複雜,那麼舉個簡單的栗子:

10、Octave中的function值是值傳遞還是地址傳遞呢?




1、訪問矩陣的特定元素值

A(n,m) = 10;%該語句是將A矩陣第n行m列值置為10
2、獲取矩陣的某一行或某一列

k = A(1,:);%獲取A矩陣的第1行
l = A(:,2);%獲取A矩陣的第2列
m = A(:,[1,3]);%獲取A的第1列和第三列

3、為矩陣加一列全為1的列
A = [ones(size(A,1),1) A];
%這裡size(A,1)為計算A的行數,第二個引數改為2時表示為列數
%ones(n,m)為初始化一個n*m的全為1的矩陣
%[A B]表示A作為列插到B的前面
%[A;B]表示作為行插入
4、點運算。

(這裡說一下,開始我一直以為.*和*其實差別不大呢,以為點乘是表明兩個元素做矩陣乘法,即認為點代表矩陣運算,如果不滿足條件,則轉置。其實發現並不是我想的那樣。)

點運算是對應元素運算

     Ⅰ.維度相同 對應元素運算

>> a=[1,2;3,4]
a =
   1   2
   3   4
>> a.*a
ans =
    1    4
    9   16
>> a*a
ans =
    7   10
   15   22


     Ⅱ.行維度相同,則每行對應元素運算(列也是同樣的套路)。

>> B = [2,3];
>> a.*B
ans =
    2    6
    6   12
>> a*B
error: operator *: nonconformant arguments (op1 is 2x2, op2 is 1x2)

5、subplot

經常用法 subplot(n,m,index);其主要作用是將當前視窗分為n行m列個子區域,在index的區域繪圖。      

6、A=[m:gap:n];從m按步長為1增長到n座位A矩陣的元素

>> A = [1:1:20]
A =

    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20
7、A = [m<n]是什麼意思

從下面可以看出來把a中大於等於4的值全部置為0,小於4的置為1;(目測可以與find函式聯手幹些事)

>> a = [1:1:10]
a =

    1    2    3    4    5    6    7    8    9   10

>> b = [a<4]
b =

   1   1   1   0   0   0   0   0   0   0

>>

8、Octave中的...是什麼意思

例如:

retval = [Image<partition1].*Image*0.3+[Image<partition2].*[Image>=partition1]...
        .*(0.105+(Image-0.3)*2.6333)+[Image>=partition2].*(1+(Image-1)*0.3);

在Octave中一句話比較長寫不下,但是換行編譯器又不知道,所以...是來告訴編譯器是換行了

9、上邊8這個例子可能寫的比較複雜,那麼舉個簡單的栗子:

有個這樣的行向量

>> a = [1:1:10]
a =

    1    2    3    4    5    6    7    8    9   10
我們想讓他小於6的元素變大二倍,大於等於6的變大3倍並減去1,你會想到怎麼做

對,作為一個初學者可能想到就是我for迴圈唄,

喂喂喂,這可是matrix 的強大工具,for迴圈會降低效率的。

對參照7步的方式可以這樣做

 ﲛĀ>> b = [a<6].*a*2+[a>=6].*(a*3-1)
b =

    2    4    6    8   10   17   20   23   26   29

怎麼理解[a<6].*a*2+[a>=6].*(a*3-1)這個式子呢?

首先分開看(以"+"或“-”分開(split)看一下),

①、[a<6].*a*2

     首先[a<6] = 1 1 1 1 1 0 0 0 0 0

     .*a後:變成 1 2 3 4 5 0 0 0 0 0

     *2後: 程式設計 2 4 6 8 10 0 0 0 0 0

②、[a>=6].*(a*3-1)

       (a*3-1):2    5    8   11   14   17   20   23   26   29

       [a>=6]:0   0   0   0   0   1   1   1   1   1

       最後.* :  0    0    0    0    0   17   20   23   26   29

最後①+②:就是 2    4    6    8   10   17   20   23   26   29嘍

通過看上邊的運算你可能會想:我後邊a*3後對前邊的a的值是否有影響呢?

顯然,這是沒有任何影響的,只是在記憶體中的數的運算,或是在暫存器中運算,沒有實際改變該變數那塊記憶體的資料。

由此又聯想到Octave中這function的問題,我們知道Java面向物件,傳入引數是物件的話一般是引用,在這裡矩陣這總資料結構是地址傳遞還是值傳遞呢?

由此引入下一個問題

10、Octave中的function值是值傳遞還是地址傳遞呢?

影象灰度線性變化函式

function [retval] = linearChange (Image,partition1,partition2)
figure;
r=[0:0.001:1];
s=[r<0.35].*r*0.3+[r<=0.65].*[r>=0.35].*(0.105+2.6333*(r-0.35))+[r>0.65].*(1+0.3*(r-1));
plot(r,s);title("linear");
retval = [Image<partition1].*Image*0.3+[Image<partition2].*[Image>=partition1]...
        .*(0.105+(Image-0.3)*2.6333)+[Image>=partition2].*(1+(Image-1)*0.3);
Image = retval;%改變了矩陣
partition1 = 10;%改變了引數
endfunction
%呼叫變化函式
partition1 = 0.35;
partition2 = 0.65;
C = linearChange(B,partition1,partition2);
figure;
imshow(B);
disp(partition1);
figure;
subplot(1,2,1);
imshow(C);
subplot(1,2,2);
imhist(C);

0.35000
結果1為原圖,作為函式的Image引數,2為函式處理後那個引數,3為函式返回的結果。

如果是地址傳遞2與3一樣,顯然告訴我們它不是地址傳遞。


那麼有引用嗎?遺憾告訴你沒有。