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
:的活用——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矩陣,元素均為1false(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);