2010-12-15 96 views
4

J'ai une série de paires de points XY dans MATLAB. Ces paires décrivent des points autour d'une forme dans une image; ils ne sont pas une fonction, ce qui signifie que deux points ou plus peuvent exister pour chaque valeur x.Obtenir des points intermédiaires générés par plot() dans MATLAB

Je peux tracer ces points individuellement en utilisant quelque chose comme

plot(B(:,1),B(:,2),'b+'); 

Je peux aussi utiliser parcelle pour relier les points:

plot(B(:,1),B(:,2),'r'); 

Ce que je suis en train de récupérer mes propres valeurs de point I peut utiliser pour connecter les points afin que je puisse les utiliser pour une analyse plus approfondie. Je ne veux pas de graphe entièrement connecté et j'ai besoin de quelque chose basé sur les données, pas seulement sur le graphique que plot() produit. J'aimerais juste avoir plot() générer ces points (comme il semble le faire dans les coulisses), mais j'ai essayé d'utiliser les linseries retournées par plot() et cela ne fonctionne pas comme je le comprends ou juste ne me donne pas ce que je veux.

Je pense que c'était un problème d'interpolation, mais les points ne comprennent pas de fonction; ils décrivent une forme. Essentiellement, tout ce dont j'ai besoin sont les points que plot() semble calculer; lignes droites reliant une série de points. Une courbe serait un bonus et me sauverait le chagrin en aval.

Comment est-ce que je peux faire ceci dans MATLAB?

Merci!

Edit: Oui, une image serait utile :)

Les points bleus sont les valeurs de points réels (x, y), tracée en utilisant le premier tracé() appel ci-dessus. Le contour rouge est le résultat de l'appel à plot() en utilisant la deuxième approche ci-dessus. J'essaie d'obtenir les données ponctuelles du contour rouge; en d'autres termes, les points reliant les points bleus. alt text

+0

Une image échantillon aiderait énormément ... vous savez , vaut mille mots et tout. ;) – gnovice

+0

Ceci est vrai. Une seconde .... –

+0

@Mike O'Malley: voir http://www.mathworks.com/help/techdoc/ref/interp1.html pour l'interpolation linéaire. C'est ce que fait l'intrigue en connectant des points de données adjacents. – zellus

Répondre

6

Adrien definitely has the right idea: définir un système de coordonnées paramétrique, puis effectuer une interpolation linéaire sur les coordonnées x et y séparément. Une chose que je voudrais ajouter est une autre façon de définir votre coordonnée paramétrique afin que vous puissiez créer des points d'interpolation uniformément espacés autour de la forme entière en une seule passe.La première chose que vous voulez faire, si vous avez pas déjà, est assurez-vous que le dernier point de coordonnées reconnecte à la première en reproduisant le premier point et l'ajouter à la fin:

B = [B; B(1,:)]; 

Ensuite, en calculant la la distance totale entre les points suivants en prenant la somme cumulative, vous pouvez obtenir une paramétrique coordonnée qui fait de petits pas pour les points rapprochés et étapes plus grandes pour les points éloignés:

distance = sqrt(sum(diff(B,1,1).^2,2)); %# Distance between subsequent points 
s = [0; cumsum(distance)];    %# Parametric coordinate 

maintenant, vous pouvez interpoler une nouvelle série de points qui sont uniformément espacés autour du bord le long des lignes droites joignant vos points en utilisant la fonction INTERP1Q :

sNew = linspace(0,s(end),100).'; %'# 100 evenly spaced points from 0 to s(end) 
xNew = interp1q(s,B(:,1),sNew);  %# Interpolate new x values 
yNew = interp1q(s,B(:,2),sNew);  %# Interpolate new y values 

Ces nouveaux ensembles de points comprendront pas nécessairement les originalités, donc si vous voulez être sûr que les points d'origine apparaissent également dans la nouvelle série, vous pouvez effectuer les opérations suivantes:

[sAll,sortIndex] = sort([s; sNew]); %# Sort all the parametric coordinates 
xAll = [B(:,1); xNew];    %# Collect the x coordinates 
xAll = xAll(sortIndex);    %# Sort the x coordinates 
yAll = [B(:,2); yNew];    %# Collect the y coordinate 
yAll = yAll(sortIndex);    %# Sort the y coordinates 


eXEMPLE:

Voici un exemple pour montrer la façon dont le code ci-dessus effectue (I utilise 11 paires de coordonnées x et y, dont l'une est répétée pour des raisons de co exemple mplete):

B = [0.1371 0.1301; ... %# Sample data 
    0.0541 0.5687; ... 
    0.0541 0.5687; ... %# Repeated point 
    0.0588 0.5863; ... 
    0.3652 0.8670; ... 
    0.3906 0.8640; ... 
    0.4090 0.8640; ... 
    0.8283 0.7939; ... 
    0.7661 0.3874; ... 
    0.4804 0.1418; ... 
    0.4551 0.1418]; 
%# Run the above code... 
plot(B(:,1),B(:,2),'b-*'); %# Plot the original points 
hold on;     %# Add to the plot 
plot(xNew,yNew,'ro');  %# Plot xNew and yNew 

alt text

+0

+1 pour fermer la boucle. Btw, la façon dont vous définissez la coordonnée s est plus qu'une coordonnée paramétrique: une coordonnée curviligne. – Adrien

+1

Le seul problème avec la façon dont vous définissez s est que vous pourriez rencontrer des problèmes si vous avez un point en double. Ce cas n'est pas pathologique ou rare. Par exemple, si vous souhaitez utiliser une interpolation basée sur une spline entre les points faisant un point double ou un point triple est un moyen d'ajouter des discontinuités dans la deuxième ou la première dérivée de la courbe. – Adrien

+0

@Adrien: Vous avez raison sur les points en double, mais je n'ai pas considéré le problème ici puisque le PO cherchait spécifiquement une interpolation linéaire. Ce serait certainement une préoccupation pour l'interpolation basée sur les splines, mais je crois que l'on pourrait facilement y remédier en supprimant les doublons. – gnovice

2

Je voudrais tout d'abord définir une paramétrique de coordonnées le long des différents segments (à savoir entre les points de données)

s = 1:size(B,1); 

Ensuite, il suffit d'utiliser interp1 pour interpoler dans l'espace s. par exemple. Si vous voulez générer 10 valeurs sur la ligne entre les points de données 5 et 6:

s_interp = linspace(5,6,10); % parametric coordinate interpolation values 
x_coord = interp1(s,B(:,1),s_interp,'linear'); 
y_coord = interp1(s,B(:,2),s_interp,'linear'); 

Cela devrait faire l'affaire.

A.

0

En fait, il y a une fonction Matlab "improfile", ce qui pourrait vous aider dans votre problème. Disons que ce sont les 4 coordonnées que vous voulez trouver les emplacements entre ces coordonnées.

xi=[15 30 20 10]; 
yi=[5 25 30 50]; 

figure; 
plot(xi,yi,'r^-','MarkerSize',12) 
grid on 

enter image description here

Juste générer une image aléatoire et exécuter la fonction

n=50; % total number of points between initial coordinates 
I=ones(max([xi(:);yi(:)])); 
[cx,cy,c] = improfile(I,xi,yi,n); 

hold on, plot(cx,cy,'bs-','MarkerSize',4) 

enter image description here

Hope it helps