dire que j'ai étiqueté une image avec scipy.ndimage.mesutions.Label Comme: Qu'est-ce qu'un moyen rapide de collecter les coordonnées appartenant à chaque étiquette? C'est à dire. Quelque chose comme: p> Je travaille avec des images comportant ~ 15 000 x 5 000 pixels de taille, et environ la moitié des pixels de chaque image sont étiquetés (c.-à-d. Non-zéro). p> plutôt que d'itération à travers l'image entière avec Edit: p> Quel algorithme est le plus rapide dépend de la taille de l'image marquée par rapport au nombre d'étiquettes qu'il a. Warren Weckesser et Salvador Dali / Bhat's Méthodes de Irshad (qui sont basés sur Les résultats d'un petit test: P> nditer code>, serait-il plus rapide de faire quelque chose comme
np.where (étiquette IMG ==) code> pour chaque Étiquette? P>
np.nonzero code> et
np.where code>) tous semblent à échelle linéairement avec le nombre d'étiquettes, alors que l'itération de Chaque élément d'image avec
nditer code> échelle évidemment linéairement avec la taille de l'image marquée. p>
size: 1000 x 1000, num_labels: 10
weckesser ... 0.214357852936s
dali ... 0.650229930878s
nditer ... 6.53645992279s
size: 1000 x 1000, num_labels: 100
weckesser ... 0.936990022659s
dali ... 1.33582305908s
nditer ... 6.81486487389s
size: 1000 x 1000, num_labels: 1000
weckesser ... 8.43906402588s
dali ... 9.81333303452s
nditer ... 7.47897100449s
size: 1000 x 1000, num_labels: 10000
weckesser ... 100.405524015s
dali ... 118.17239809s
nditer ... 9.14583897591s
4 Réponses :
Vous pouvez faire quelque chose comme ceci (let qui vous donnera ce que vous voulez: p> < Pré> xxx pré> si cela sera plus rapide - est à la hauteur de la référence à déterminer. P> par Warren's Suggestion, je n'ai pas besoin d'utiliser unique et de faire P> img code> est votre original nd.array)
Parce que img code> a été calculé à l'aide de
scipy.ndimage.mesurements.label () code>, il n'est pas nécessaire d'appeler
np.unique (img) code> pour obtenir ses valeurs uniques. Nous savons déjà que les valeurs sont 0, 1, 2, ...,
num_labels code>.
Num_Labels CODE> est également connu, car il s'agit de la deuxième valeur de retour de l'étiquette
() code>. Vous pouvez donc remplacer
np.unique (IMG) [1:] code> avec la plage
(1, num_labels + 1) code>.
Essayez ceci:
>>> z array([[0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0], [2, 2, 0, 0, 0, 0], [2, 2, 0, 0, 0, 0]]) >>> {i:zip(*np.where(z==i)) for i in np.unique(z) if i} {1: [(0, 1), (1, 1), (2, 1)], 2: [(4, 0), (4, 1), (5, 0), (5, 1)], 3: [(3, 4)]}
Pourquoi avez-vous besoin si je code> à la fin de votre compréhension?
Consultez mon commentaire à la réponse de @ Salvadordali sur l'utilisation de np.unique (img) code>. Vous pouvez remplacer
pour i dans np.unique (z) si i code> avec
pour i in gamme (1, num_labels + 1) code>.
Oh je vois. Le si je code> exclut les pixels étiquetés comme 0s.
Voici une possibilité: J'ai appelé ce script get_label_indices.py code>. Voici un échantillon exécutif: p>
Je pense que votre méthode est la plus rapide des solutions proposées, mais je n'ai pas encore eu de tests en profondeur. Étonnamment, pour un grand nombre d'étiquettes (environ 30 000), il semble que cela semble itérant à travers chaque pixel d'image (environ 75 000 000 d'entre eux) finissent par être plus rapide. Quand je fais des comparaisons approfondies, je vais mettre à jour ma question avec ce que je trouve.
Je viens de faire une comparaison plus détaillée. Lemme sais ce que tu penses.
@bennlich belle comparaison. J'ai soupçonné que la performance dépendrait fortement de la densité des étiquettes et du nombre d'étiquettes uniques.
Ceci est fondamentalement une opération argsort code>, avec quelques travaux supplémentaires pour obtenir le format souhaité:
def sorting_based(img, nlabels):
img_flat = img.ravel()
label_counts = np.bincount(img_flat)
lin_idx = np.argsort(img_flat)[label_counts[0]:]
coor = np.column_stack(np.unravel_index(lin_idx, img.shape))
ptr = np.cumsum(label_counts[1:-1])
out = dict(enumerate(np.split(coor, ptr), start=1))
return out
np.where (iMG == étiquette) code> (ou équivalent
np.nonzero (étiquette IMG ==) code>) sera plus rapide que itérant avec
nditer code >. Cependant, avez-vous réellement besoin des indices? Si vous souhaitez extraire des valeurs d'un autre tableau,
data [iMG == Label] code> sera plus rapide que
i, j = np.where (étiquette IMG ==); Data [j, j] code>.
@Joekington s'avère
np.where code> ne sera pas toujours plus rapide que itération. Je viens de faire des modifications à ma question qui le reflètent.
Avez-vous éliminé l'utilisation de
np.unique code> des réponses de Salvador Dali et Bhat Irshad?
@Warrenweckesser oui
Related: alternative plus rapide à numpy.where?