TransWikia.com

Найти для каждого изображения по два ближайших,

Stack Overflow на русском Asked on February 12, 2021

У меня есть список словарей, где ключ – имя изображения,значение – координаты из exif.

{'IMG_0003_1.tif': {'Latitude': 46.292602599999995, 'Longitude': -119.7299495, 'Altitude': 426.316}}
{'IMG_0004_1.tif': {'Latitude': 46.29282, 'Longitude': -119.7301617, 'Altitude': 477.151}}
{'IMG_0005_1.tif': {'Latitude': 46.2929581, 'Longitude': -119.7303228, 'Altitude': 477.222}}
{'IMG_0006_1.tif': {'Latitude': 46.2931217, 'Longitude': -119.7304816, 'Altitude': 477.432}}
{'IMG_0007_1.tif': {'Latitude': 46.2932815, 'Longitude': -119.7306418, 'Altitude': 477.962}}
{'IMG_0008_1.tif': {'Latitude': 46.293439299999996, 'Longitude': -119.730806, 'Altitude': 477.823}}
{'IMG_0009_1.tif': {'Latitude': 46.2935699, 'Longitude': -119.730942, 'Altitude': 477.506}}
{'IMG_0010_1.tif': {'Latitude': 46.2937307, 'Longitude': -119.7311043, 'Altitude': 477.314}}
{'IMG_0011_1.tif': {'Latitude': 46.2939978, 'Longitude': -119.7313743, 'Altitude': 476.604}}
{'IMG_0012_1.tif': {'Latitude': 46.2940508, 'Longitude': -119.7314279, 'Altitude': 476.334}}
{'IMG_0013_1.tif': {'Latitude': 46.2942515, 'Longitude': -119.7316253, 'Altitude': 475.738}}
{'IMG_0014_1.tif': {'Latitude': 46.294383599999996, 'Longitude': -119.7317627, 'Altitude': 476.546}}
{'IMG_0015_1.tif': {'Latitude': 46.2945286, 'Longitude': -119.73191200000001, 'Altitude': 477.327}}
{'IMG_0016_1.tif': {'Latitude': 46.294699699999995, 'Longitude': -119.73208890000001, 'Altitude': 477.12}}
{'IMG_0017_1.tif': {'Latitude': 46.294854099999995, 'Longitude': -119.732251, 'Altitude': 476.749}}
{'IMG_0018_1.tif': {'Latitude': 46.294931899999995, 'Longitude': -119.7323415, 'Altitude': 475.614}}
{'IMG_0019_1.tif': {'Latitude': 46.2949305, 'Longitude': -119.73230360000001, 'Altitude': 475.913}}
{'IMG_0020_1.tif': {'Latitude': 46.294931299999995, 'Longitude': -119.7317773, 'Altitude': 475.696}}
{'IMG_0021_1.tif': {'Latitude': 46.294931399999996, 'Longitude': -119.7316604, 'Altitude': 475.541}}
{'IMG_0022_1.tif': {'Latitude': 46.2949279, 'Longitude': -119.7314008, 'Altitude': 475.584}}
{'IMG_0023_1.tif': {'Latitude': 46.2949282, 'Longitude': -119.7311443, 'Altitude': 475.132}}

Теперь мне нужно найти для каждого изображения по два ближайших, согласно координатам.
Как это на python сделать? Просто даже не знаю с чего начать…

2 Answers

Вот, сделал. Правда не через DataFrame

import os
from scipy.spatial import distance
from GPSPhoto import gpsphoto

dir_im='datasets/m_a1/'
im_list = os.listdir(dir_im)
list_of_dicts=[]


def dist_points(ccord1,coord2):
    dist = distance.euclidean(ccord1,coord2)
    return dist

def get_coords(d):
    lat,lon=d['Latitude'],d['Longitude']
    return lat,lon

for im in sorted(im_list):
    data_gps=gpsphoto.getGPSData(dir_im+im)
    list_of_dicts.append({im:data_gps})

new_dict = {k: v for d in list_of_dicts for k, v in d.items()}

closest = {}
for k, v in new_dict.items():
    other_photos = {key: v for key, v in new_dict.items() if key != k}
    coords1 = get_coords(v)
    for key, value in other_photos.items():
        crd=get_coords(value)
        distances = {key: dist_points(coords1, get_coords(value)) for key, value in other_photos.items()}
       two_closest = sorted(distances, key=distances.get)[:2]
       closest[k] = two_closest

Output:


{'IMG_0003_1.tif': ['IMG_0004_1.tif', 'IMG_0005_1.tif'], 'IMG_0004_1.tif':   ['IMG_0005_1.tif', 'IMG_0003_1.tif'], 'IMG_0005_1.tif': ['IMG_0004_1.tif',  'IMG_0006_1.tif'], 'IMG_0006_1.tif': ['IMG_0007_1.tif', 'IMG_0005_1.tif'],  'IMG_0007_1.tif': ['IMG_0006_1.tif', 'IMG_0008_1.tif'], 'IMG_0008_1.tif':  ['IMG_0009_1.tif', 'IMG_0007_1.tif'], 'IMG_0009_1.tif': ['IMG_0008_1.tif', 'IMG_0010_1.tif'], 'IMG_0010_1.tif': ['IMG_0009_1.tif', 'IMG_0011_1.tif'], 'IMG_0011_1.tif': ['IMG_0012_1.tif', 'IMG_0013_1.tif'], 'IMG_0012_1.tif': ['IMG_0011_1.tif', 'IMG_0013_1.tif'], 'IMG_0013_1.tif': ['IMG_0014_1.tif', 'IMG_0012_1.tif'], 'IMG_0014_1.tif': ['IMG_0013_1.tif', 'IMG_0015_1.tif'], 'IMG_0015_1.tif': ['IMG_0014_1.tif', 'IMG_0016_1.tif'], 'IMG_0016_1.tif': ['IMG_0017_1.tif', 'IMG_0015_1.tif'], 'IMG_0017_1.tif': ['IMG_0019_1.tif', 'IMG_0018_1.tif'], 'IMG_0018_1.tif': ['IMG_0019_1.tif', 'IMG_0017_1.tif'], 'IMG_0019_1.tif': ['IMG_0018_1.tif', 'IMG_0017_1.tif'], 'IMG_0020_1.tif': ['IMG_0021_1.tif', 'IMG_0022_1.tif'], 'IMG_0021_1.tif': ['IMG_0020_1.tif', 'IMG_0022_1.tif'], 'IMG_0022_1.tif': ['IMG_0023_1.tif', 'IMG_0021_1.tif'], 'IMG_0023_1.tif': ['IMG_0022_1.tif', 'IMG_0021_1.tif']}

Correct answer by Newman on February 12, 2021

У вас крайне неудобная структура хранения информации. Первое, что бы я сделал - преобразовал ее в датафрейм, столбцы которого были бы 'Im_id','Latitude','Longitude','Altitude', а каждая строчка соответствовала бы изображению.

Потом делаете двойной цикл.

Внешний - проходите по строчкам датафрейма. Для каждой строчки str запускаете внутренний цикл еще раз, просматривая последовательно датафрейм и на каждом шаге вычисляя расстояние между текущей точкой и точкой str. Вычисление скорее всего надо проводить по формуле Эвклида - корень квадратный из суммы квадратов расстояний по 'Latitude' и 'Longitude'. Это если вы не учитываете 'Altitude'. Не выходя из итерации внешнего цикла находите два наименьших значений расстояния и выводите 'Im_id' для str и изображений давших это наименьшее расстояние.

Звучит немного запутано, но на самом деле довольно не сложная программная конструкция (если предварительно преобразоваться к датафрейму).

Алгоритм можно еще немного упростить, заменив внешний цикл группировкой по имени изображения. Но для этого надо хорошо владеть методами пакета pandas.

Еще один возможный вариант решения, подобный первому выше, но быстрее его - преобразовать данные не в датафрейм, а в массив numpy. Выигрывая в скорости тут придётся немного повозиться с преобразованием имени изображения к номеру и обратно. Не знаю, оправдан-ли такой подход для ваших данных.

Наконец, если понятие "близости" для вас включает и высоту над уровнем моря, формула расстояния будет не двухкомпонентная, а трехкомпонентная.

Answered by passant on February 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP