2016-08-22 15 views
-1

我曾嘗試使用在this answer提供的代碼來檢測使用模板匹配的符號與FFT(經由fft2如何用matlab

但是,代碼只檢測到一個符號,以檢測圖像的符號的多個實例,但它不檢測所有類似的符號。

該代碼已從鏈接的帖子改編而來,如下所示。

template=im2bw(imread(http://www.clipartkid.com/images/543/floor-plan-symb-aT0MYg-clipart.png)); 
background=im2bw(imread(http://www.the-house-plans-guide.com/images/blueprints/draw-floor-plan-step-6.png)); 

bx = size(background, 2); 
by = size(background, 1); 
tx = size(template, 2); % used for bbox placement 
ty = size(template, 1); 
pos=[]; 
%// Change - Compute the cross power spectrum 
Ga = fft2(background); 
Gb = fft2(template, by, bx); 
c = real(ifft2((Ga.*conj(Gb))./abs(Ga.*conj(Gb)))); 

%% find peak correlation 
[max_c, imax] = max(abs(c(:))); 
[ypeak, xpeak] = find(c == max(c(:))); % Added to make code work 
if ~isempty(ypeak) || ~isempty(xpeak) 
pos=position; 

plot(xpeak,ypeak,'x','LineWidth',1,'Color','g'); 
rectangle('position',position,'edgecolor','b','linewidth',1, 'LineStyle', '- '); 
end 

我該如何使用上面的代碼來檢測多個符號而不是一個?

+2

你把在C,讓你只有一個點只最大值。取而代之的是從最大值開始的所有點距離。 –

+0

如何從最大值查找epsilon距離 –

+1

嘗試將c中的唯一值分爲兩組(可能使用kmeans)。一個簡單的方法就是從最大值中取出一個STD。或者採用c中的唯一值的直方圖,並嘗試查看是否可以輕鬆找到相關值下降的點。 –

回答

1

Amitay在他的評估中是正確的。順便說一句,你採取的代碼來自以下帖子:Matlab Template Matching Using FFT

該代碼僅用於檢測您指定模板中的一個匹配項。如果要檢測多個模板中,你可以用自己的優點和缺點嘗試每個不同的方法:

  1. 使用全局閾值和從互功率譜,即超過此閾值的任何值,認爲有一場比賽。
  2. 找到交叉功率譜中最大的相似度,任何與這個最大值相距一定距離的東西都會被認爲是匹配的。也許有一段距離,或一個標準偏差可能會起作用。
  3. 嘗試製作交叉功率譜中唯一值的直方圖,並找出明顯與模板和相關值無關的值之間的明顯間隔。我不會在這裏爲你實現這個,因爲它要求我們看看你的圖像,然後通過檢查直方圖來找到閾值,所以我不會爲你做到這一點。相反,你可以嘗試前兩種情況,看看它發生了什麼。

如果出現這種情況,您將不得不循環多次匹配,因此您需要遍歷在圖像中繪製矩形的代碼。


案例#1

第一種情況是非常簡單的。您只需修改find聲明,以便不用搜索具有最大值的位置,只需找到超出閾值的位置即可。

因此:

%% find peak correlation 
thresh = 0.1; % For example 
[ypeak, xpeak] = find(c >= thresh); 

案例#2

這非常類似於第一種情況,但不是發現,超過臨界值,確定哪些最大的相似度值(已完成),並且閾值高於(1 - x)*max_val,其中x是介於0和1之間的值,表示您希望遠離最大值的百分比被視爲匹配。因此,如果您想要最多5%,x = 0.05等門檻現在變成0.95*max_val。同樣,對於標準偏差,只需找到它使用std函數並確保將其轉換爲單個矢量,以便可以計算整個圖像的值,則閾值將變爲max_val - std_val,其中std_val是標準偏差的標準偏差相似度值。對於標準偏差比較

%% find peak correlation 
x = 0.05; % For example 
[max_c, imax] = max(abs(c(:))); 
[ypeak, xpeak] = find(c >= (1-x)*max_c); 

...並做到這一點:

因此,百分比比較做這樣的事

std_dev = std(abs(c(:))); 
[max_c, imax] = max(abs(c(:))); 
[ypeak, xpeak] = find(c >= (max_c - std_dev)); 

一旦你最終建立這一點,你會看到有多個匹配。現在是在圖像頂部繪製所有檢測到的模板的一個點。使用「借用」代碼的帖子,可以修改繪製檢測到的模板的代碼以繪製多個模板。

,下面你可以這樣做:

%% display best matches 
tx = size(template, 2); 
ty = size(template, 1); 
hFig = figure; 
hAx = axes; 
imshow(background, 'Parent', hAx); 
hold on; 

for ii = 1 : numel(xpeak) 
    position = [xpeak(ii), ypeak(ii), tx, ty]; % Draw match on figure 
    imrect(hAx, position); 
end