最近准备开始做数字图像处理的实验,我安装了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一样,显然告诉我们它不是地址传递。
那么有引用吗?遗憾告诉你没有。