2014-11-05 106 views
1

衆所周知,MATLAB中的histeq可以執行直方圖匹配,以便圖像的直方圖轉換爲另一個直方圖。我正在嘗試在不使用histeq的情況下執行相同的操作。我知道你需要計算兩幅圖像之間的CDF,但我不確定接下來要做什麼。我該怎麼辦?不使用histeq的兩個圖像的直方圖匹配

+0

我see.nut我想直方圖匹配兩個圖像 – 2014-11-05 18:35:12

+0

我寫了一個答案。你需要進一步的幫助嗎? – rayryeng 2014-11-07 07:19:47

+0

是的。我認爲你的代碼中cdf是錯誤的。CDFis propability,你應該使用這個:probc = cumsum(freq)/ numel(GIm); – 2014-11-07 07:33:53

回答

4

直方圖匹配涉及轉換一個圖像的直方圖,使其看起來像另一個。基本原理是分別計算每個圖像的直方圖,然後計算它們的離散值cumulative distribution functions (CDFs)。我們將第一張圖像的CDF表示爲,而第二張圖像的CDF爲。因此,將表示第一幅圖像的強度爲x的CDF值。

一旦計算出每個圖像的CDF,就需要計算一個映射,該映射將第一個圖像的一個強度轉換爲與第二個圖像的強度分佈一致。要做到這一點,對於第一幅圖像中的每個強度 - 我們稱[0,255],假設爲8位圖像 - 我們必須在第二幅圖像(也在[0,255]範圍內)找到強度,例如:

有可能是,我們不會得到正是相等的情況下,所以你需要做的是找到之間的最小差值的絕對值。換句話說,對於一個映射M,爲每個條目,我們必須找到一個強度這樣的:

你會爲所有256個值做到這一點,我們會產生一個映射。一旦你找到了這個映射,你只需要在第一個圖像上應用這個映射,使它看起來像第二個圖像的強度分佈。一個粗糙的(也許是效率低下的)算法看起來像這樣。讓im1是第一圖像(的uint8類型),而im2是(的uint8型)第二圖像:

M = zeros(256,1,'uint8'); %// Store mapping - Cast to uint8 to respect data type 
hist1 = imhist(im1); %// Compute histograms 
hist2 = imhist(im2); 
cdf1 = cumsum(hist1)/numel(im1); %// Compute CDFs 
cdf2 = cumsum(hist2)/numel(im2); 

%// Compute the mapping 
for idx = 1 : 256 
    [~,ind] = min(abs(cdf1(idx) - cdf2)); 
    M(idx) = ind-1; 
end 

%// Now apply the mapping to get first image to make 
%// the image look like the distribution of the second image 
out = M(double(im1)+1); 

out應該包含你匹配的圖像,其中將其變換第一圖像的強度分佈相匹配的第二個圖像。特別注意out聲明。 im1的強度範圍跨度在[0,255]之間,但MATLAB的數組索引起始於。因此,我們需要爲im1的每個值加1,以便我們可以正確地索引到M以產生我們的輸出。然而,im1的類型是uint8,如果你嘗試超越255,那麼MATLAB飽和值。因此,爲了確保達到256,我們必須轉換爲超過8位精度的數據類型。我決定使用double,然後當我們爲im1中的每個值加1時,我們將跨越1到256,因此我們可以正確地索引到M。當我找到最小化差異的位置時,也不要這樣,因爲數據類型從[0,255]跨度,我也必須減去1。

+0

請參閱以下鏈接:[鏈接](http://fourier.eng.hmc.edu/e161/lectures/contrast_transform/node3.html) – 2014-11-07 07:36:18

+0

@abbasmahmudi除了規範'cumsum'結果,代碼是正確的。該框圖證明了這一點,但感謝您的鏈接! – rayryeng 2014-11-07 07:42:30

+0

現在好了,這是正確的。謝謝你的回答 – 2014-11-07 07:54:38