2015-02-05 71 views
0

我有一個任務是計算從輸入圖像I提取的子圖像的平均值。讓我們來解釋我的任務。我有一個圖像I(即9x9)和一個窗口(即尺寸爲3x3)。該窗口將從圖像的左上角到右下角運行。因此,它會將輸入圖像提取到多個子圖像中。我想計算這些子圖像的平均值。你能給我建議一些matlab代碼來計算它嗎?如何計算圖像I中所有子圖像的平均值

這是我的解決方案。但它不起作用。

  • 首先,我定義的窗口爲高斯
  • 其次,高斯函數將從左上使用到右下卷積函數運行。 (需要注意的是,必須使用高斯核)
  • 計算每個子窗口

    %% Given Image I,Defined a Gaussian Kernel 
    sigma=3; 
    K=fspecial('gaussian',round(2*sigma)*2+1,sigma);  
    KI=conv2(I,K,'same'); 
    %% mean value 
    mean(KI) 
    

    的平均值在這裏的問題是,平均值關閉所有子圖像將有大小相似的圖像I因爲圖像中的每個像素都會產生一個子圖像。但我的代碼只返回一個值。什麼是問題?

enter image description here

+0

對於2D矩陣/信號,「平均值(KI)」將給出單個行向量,其中每個元素是位於該KI處索引處的**列**的均值。根據你的描述,這當然不是你想要的。無論哪種方式,我都提供了一個答案。 – rayryeng 2015-02-05 18:59:20

+0

是的,我錯誤地使用函數意味着(KI) – Jame 2015-02-05 19:04:28

回答

1

如果這是你來計算各個子圖像中的平均值,一旦你與高斯內核過濾你的形象的願望,只要你的卷積圖像與mean or average filter。這將收集您的原始圖像和每個輸出位置的子圖像,您將計算平均值。

在初始假設屏幕尺寸爲3 x 3的情況下,只需將conv2與具有全部1/9係數的3 x 3屏蔽結合使用即可。換句話說:

%// Your code 
%% Given Image I,Defined a Gaussian Kernel 
sigma=3; 
K=fspecial('gaussian',round(2*sigma)*2+1,sigma);  
KI=conv2(I,K,'same'); 

%// New code 
mask = (1/9)*ones(3,3); 
out = conv2(KI, mask, 'same'); 

out每個位置會給你什麼樣的平均值是在您的高斯濾波結果每個3×3子圖像。

您還可以使用fspecial與標記average並指定掩碼的大小/寬度來創建平均掩碼。鑑於你已經在你的代碼中使用它,你已經知道它的存在。同樣,你也可以這樣做:

mask = fspecial('average', 3); 

上面的代碼假定寬度和麪罩的高度是一樣的,所以它會創造一切1/9係數的3×3面具。

除了

conv2被設計用於一般的2D信號。如果您想要過濾圖片,我建議您改用imfilter。您應該可以訪問它,因爲fspecial是圖像處理工具箱的一部分,所以imfilter也是如此。 imfilter已知比conv2效率更高,並且如果可用的話也使用Intel Integrated Performance Primitives (Intel IPP)(基本上,如果您在具有支持IPP的Intel處理器的計算機上運行MATLAB)。因此,你應該執行你的過濾是這樣的:

%// Your code 
%% Given Image I,Defined a Gaussian Kernel 
sigma=3; 
K=fspecial('gaussian',round(2*sigma)*2+1,sigma);  
KI=imfilter(I,K,'replicate'); %// CHANGE 

%// New code 
mask = fspecial('average', 3); 
out = imfilter(KI, mask, 'replicate'); %// CHANGE 

replicate標誌是處理邊界條件。當您的蒙版超出原始圖像的邊界時,replicate只會複製圖像每一邊的邊框,以便在執行濾鏡時蒙版可以舒適地適合圖像。

編輯

鑑於你的評論,你想提取見於KI子圖像。您可以使用功能強大的im2col功能,它是圖像處理工具箱的一部分。你怎麼稱呼它,像這樣:

B = im2col(A,[m n]); 

A將是你的輸入圖像,並B將是一個矩陣是大小mn x L的地方L是存在於你的形象和m可能的子圖像的總數量,n分別是每個子圖像的高度和寬度。 im2col的工作原理是,對於圖像中存在的每個子圖像,它會對它們進行扭曲,以使其適合於B中的單個列。因此,B中的每一列都會生成一個單獨的子圖像,該子圖像被翹曲成一列。然後,您可以使用B中的每列進行GMM建模。

但是,im2col只返回不超出邊界的有效子圖像。如果你想要處理邊緣和角落的情況下,你需要第一個圖像。使用padarray來方便填充。因此,你要問什麼,我們只是做:

Apad = padarray(KI, [1 1], 'replicate'); 
B = im2col(Apad, [3 3]); 

第一行代碼將墊的圖像,讓您有包圍圖像的1個像素的邊界。這將允許您在邊界位置提取3 x 3個子圖像。我使用replicate標誌,以便您可以簡單地複製邊框像素。接下來,我們使用im2col,以便獲得3 x 3個子圖像,然後將其存儲在B中。因此,B將成爲9 x L矩陣,其中每列爲您提供3 x 3的子圖像。

請注意im2col翹曲列專業格式的這些列。這意味着對於您所擁有的每個子圖像而言,它會將子圖像中的每一列都疊加在一起,從而爲您提供9 x 1列。您將有L全部子圖像,並且它們水平連接以產生9 x L矩陣。此外,請記住,子圖像從頂部到底部被讀取爲,然後從左到右被讀取爲,因爲這是以列主要順序操作的MATLAB的性質。

+0

謝謝rayryeng,它是非常明確的代碼。但是,我有一個簡短的問題。如果我想從I.中提取這些子圖像,該怎麼做。因爲卑鄙是我的一個簡單任務。另一個任務是找到每個子圖像使用高斯混合模型的pdf。對於高斯混合器模型完成。現在我想爲每個子圖像應用該功能。預先感謝 – Jame 2015-02-05 18:59:33

+0

@ user8430 - 使用'im2col'。我會更新我的答案。 – rayryeng 2015-02-05 19:00:07

+0

@ user8430 - 我已經更新了我的答案。祝你好運! – rayryeng 2015-02-05 19:07:06

相關問題