簡體   English   中英

Matlab編碼說明

[英]Explanation of the Matlab coding

我在互聯網上找到了這個Matlab代碼。 它實際上是整個代碼的一部分,可以在這里找到。 有人可以逐行解釋發生了什么。 我真的很絕望...

% ------------- % This is code to make the edge detecting filter % ----%
function filter=gaussfilt(N)

% calculate alpha so the filter fills all N points
alpha=N;
first=-(1-N/2)*exp(-(1-N/2)^2/alpha);
count=0;
while first<.1*(-(1530/4000*N-N/2)*exp(-(1530/4000*N-N/2)^2/alpha))
    count=count+1;
    alpha=N*500*count;
    first=-(1-N/2)*exp(-(1-N/2)^2/alpha);
end

for n=1:N
     filter(n)=-(n-N/2)*exp(-(n-N/2)^2/alpha);   % d/dt of a gaussian
end
filter=filter/sum(abs(filter));     % normalization

return

此函數嘗試返回高斯梯度-當您將其與一組o個數據點進行卷積運算時,它將檢測數據中的邊沿,同時平滑平均水平沒有突然變化的區域中的點。 這是N = 15時的輸出:

在此處輸入圖片說明

但是,如果將N增加到20,則會發生瘋狂的事情,因為代碼坦率地說是錯誤的(以及丑陋的)。 最終,您得到的不是一條漂亮的曲線,而是一條直線-一個可怕的過濾器。 這是因為嘗試為alpha計算新值是可怕的。

Robert P已經提供了有關代碼執行情況的分步說明。讓我向您展示“正確的方式”編寫此函數(您將看到我使用了Robert提到的某些技術,以及一些其他的技術)。我會解釋)...

function myFilter = gaussfilt2(N, alpha)
% myFilter = gaussfilt(N, alpha)
% returns an N point normalized array of filter coefficients
% corresponding to the gradient of a Gaussian over the interval [-1 1]
% with a standard deviation of 1/alpha 
% in other words, the higher alpha, the sharper the filter
% default value for alpha is 3

if ~exist('alpha', 'var')
  alpha = 3; 
end 

x = linspace( -1, 1, N); % create a vector of N values between -1 and 1 inclusive
sigma = 1.0 / alpha; % convert from alpha to sigma as used in Gaussian formula

% compute first derivative, but leave constants out
% we will normalize later by summing over the coefficients
myFilter = -x .* exp( -(x.^2)/(2*sigma.^2)); % using .* for element-by-element operation

% normalize:
myFilter = myFilter / sum( abs( myFilter ) ); % absolute sum of coefficients is now one

當您使用N=150alpha = 3運行此函數時,曲線如下所示:

在此處輸入圖片說明

需要說明一些技巧:

當您在函數聲明正下方啟動注釋塊(用%表示)時,在文檔中,當用戶請求此函數的幫助時,該塊中的所有內容都會顯示給用戶(例如,通過在另一個腳本中突出顯示函數名並按F1)。 總是一個好主意

矢量化 Matlab在執行“顯式循環”方面非常糟糕,並且在“隱式循環”方面確實非常出色。 只要有可能,您都希望一次對一堆值進行“相同的計算”。 在這種情況下,我using the linspace(x1,x2,n) function. This returns an equally spaced array of計算向量x function. This returns an equally spaced array of function. This returns an equally spaced array of values from x1 to x2(含) function. This returns an equally spaced array of n個values from function. This returns an equally spaced array of 現在,我可以用一個語句來計算整個函數

逐元素相乘 Matlab實際上是用於矩陣處理的(即“ Matlab”中的“ Mat”-它代表矩陣,而不是數學)。 如果您有兩個向量ab ,並且要逐個元素相乘(因此結果為[a(1)8b(1) a(2)*b(2) ... a(n)*b(n)] ),則使用.*運算符。

靈活性代替“硬接線” alpha值,使其成為第二個參數使您可以重用相同的功能並更改濾鏡的清晰度。 允許用戶省略該變量並提供默認值意味着該函數仍可被該函數僅具有單個參數時編寫的程序使用。 exist('alpha', 'var')名稱為'alpha'的變量( 'var'exist('alpha', 'var')調用將返回true 在函數前面添加~否定結果-就像其他語言中的If Not一樣。

我完全同意弗洛里斯(Floris)的觀點,但會為您提供一些線索。 根據您的問題,我假設您以前從未使用過MATLAB,因此,我強烈建議您嘗試一些在線提供的教程。

function filter=gaussfilt(N)

這定義了函數gaussfilt的名稱,輸入變量N和輸出變量filter 您的m文件必須另存為gaussfilt.m

filter是MATLAB中許多內置函數之一,因此不是一個好的變量名。 我建議您使用諸如gauss_filter的名稱,或者基本上使用其他任何名稱。 在您的情況下,這可能無關緊要,因為您沒有使用filter功能,但是使用這種名稱是一個壞習慣。 這也帶有諸如sizelengthmax等名稱。

alpha=N;
first=-(1-N/2)*exp(-(1-N/2)^2/alpha);
count=0;

這些行只為變量名賦值。 exp()是自然指數。 count用於跟蹤while循環循環的次數。

while first<.1*(-(1530/4000*N-N/2)*exp(-(1530/4000*N-N/2)^2/alpha))
    count=count+1;
    alpha=N*500*count;
    first=-(1-N/2)*exp(-(1-N/2)^2/alpha);
end

只要滿足以下條件,就會計算whileend之間的所有內容。 條件應該是不言自明的。

first < .1*(-(1530/4000*N-N/2)*exp(-(1530/4000*N-N/2)^2/alpha))

count增加,因此您可以跟蹤執行循環的次數。 但是,從不使用它,因此在此情況下是不必要的。 但是,我建議您保留該計數器,並在while循環中包含另一個條件,即如果count > 1e6或其他較大的數字,它應該停止運行。 這樣,您可以避免在其他條件不滿足的情況下永遠運行的循環。

for n=1:N
     filter(n)=-(n-N/2)*exp(-(n-N/2)^2/alpha);   % d/dt of a gaussian
end

for n = 1:N是一個將運行N次的循環,其中n第一次為1 ,第二次為2 ,依此filter(n) = .. 。filter filter(n) = ..將值賦給filter變量中的第n個位置,因此創建長度為N的向量。這是創建向量的一種糟糕的壞方法。 您應該始終為該向量分配內存,以避免向量在循環內增長。 “增長中”的向量非常非常慢。 因此,在開始循環之前,應執行以下操作:

filter = zeros(1,N);

這將創建一個零向量。 這可能有點太多,但是將值分配給filter的更好方法是使用arrayfun

filter = arrayfun(@(n) (-(n-N/2) * exp(-(n-N/2)^2 / alpha)), 1:N);

查看此答案中的第 6點,以了解原因。

最后一行:

filter=filter/sum(abs(filter));

好吧,您將filter值除以這些值的總和,從而創建一個總和等於1的新filter 這是您將從函數獲得的輸出。

使用該函數時,必須編寫如下內容:

filter_vector = gaussfilt(N) % where N is an integer

最后,請使用空格! 它更容易閱讀!

再次,我推薦一些MATLAB教程...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM