2010-03-11 13 views
1

link textSuppression de pixels supplémentaires après avoir diminué à un point et en sélectionnant le pixel correct comme point de croisement avec Matlab

Basé sur le lien ci-dessus, j'ai réussi à obtenir le point de croisement, mais parfois je reçois 2 ou plus de résultats. J'ai 10 images similaires avec la croix légèrement déplacée dans chaque image. Est-il possible de supprimer les pixels restants qui sont très éloignés des 9 autres images en les comparant au point de croisement de la 1ère image? Comme le mouvement est assez petit, est-ce exact de dire que le pixel qui devrait être sélectionné parmi les 2 résultats ou plus que j'ai obtenus devrait être celui qui a la valeur la plus proche que j'ai du pixel de l'image précédente? Y a-t-il un moyen de faire cela? Merci!

Répondre

1

Lorsque vous obtenez un résultat, êtes-vous sûr que c'est correct? Si oui, vous pourriez faire quelque chose comme:

function pos = ChoosePosition(posGood, posA, posB) 
%# posGood is the known good answer, posA and posB are candidates 
if norm(posA - posGood) > norm(posB - posGood) 
    pos = posB; 
else 
    pos = posA; 

Si vous voulez automatiser tout, vous pouvez recueillir toutes les mesures dans une matrice NX2 et procédez comme suit:

function [dist, idx] = RankPositions(pos) 
%# pos should be an Nx2 matrix of x,y candidate positions 

dist = pos - repmat(mean(pos), length(pos), 1); %# this is for octave, matlab might handle pos - mean(pos) 
dist = norm(dist, 'rows'); 
[dist, idx] = sort(dist); 

%# one liner: 
%# [dist, idx] = sort(norm(pos - repmat(mean(pos), length(pos), 1)), 'rows')); 

Cela vous donnera un assortiment classé de la distance de chaque point de la moyenne de tous les points. Alors, puisque vous savez que vous avez (par exemple) 10 images mais avez 14 (ou autre) résultats, vous pouvez simplement prendre les 10 distances les plus faibles comme les véritables positions:

realpos = pos(idx(1:10)); 
+0

Matlab peut gérer pos-moyenne (pos) en utilisant bsxfun comme ceci: bsxfun (@ moins, pos, moyenne (pos)) – Jonas

+0

@Jonas - merci. C'est un de ces idiomes avec lesquels je ne me suis jamais senti à l'aise. – mtrw

1

Oui. Vous pouvez essayer d'effectuer une détection des valeurs aberrantes sur les coordonnées. Cela nécessite que la plus grande accumulation de coordonnées se trouve au vrai centre de la croix. De ce que vous décrivez, cette hypothèse est satisfaite.

%# Assume the cross should be around [0,0], 
%# and you are storing the coordinates in a cell array 

coordCell = {[0,0],[0.1,-0.05;4,4],[0.3,0.2;-2,5],[-0.25,0;2,-3]}; 

%# collect the coordinates of all images 
allCoords = cat(1,coordCell{:}); 


%# take the median 
medCoord = median(allCoords,1); 

%# calculate the residuals, take the median of them 
res2 = bsxfun(@minus,allCoords,medCoord).^2; 
medRes = median(res2,1); 

%# outliers are some factor above the median residual 
%# Rousseeuw & Leroy, 1987, calculated how much for us (1.4826). 
%# The factor k is the stringency (how many 'sigmas' do you have 
%# to be away from the median to be counted an outlier) 
%# A common value for k is 3. 
k = 3; 
testValue = bsxfun(@rdivide,res2,medRes*1.4826^2); 
outlierIdx = any(testValue>k^2,2); 

%# now you can throw out the outliers 
allCoords(outlierIdx,:) = [];