首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python -地球流浪者距离

Python -地球流浪者距离
EN

Stack Overflow用户
提问于 2018-03-12 11:58:01
回答 1查看 3K关注 0票数 3

我想用地球探测器的距离来比较多幅图像。

我把scipy.stats.wasserstein_distance()pyemd.emd_samples()做了比较。据我所知,wasserstein_distance()采用两种分布,即直方图,而emd_samples()则采用一维值数组,并为您计算直方图。

考虑到两种方法都使用相同的直方图,它们应该提供相同或至少相似的结果。

问题是,这两种方法提供了非常不同的结果。但是,如果我在这两种方法中传递一个扁平的图像版本,结果是非常相似的。

在我这方面是否有错误,或者这些实现中的一个有问题?

代码语言:javascript
复制
cat1 = skimage.io.imread("./cat1.jpg", as_grey=True).flatten().astype('float64')
cat2 = skimage.io.imread("./cat2.jpg", as_grey=True).flatten().astype('float64')
shuttle = skimage.io.imread("./shuttle.jpg", as_grey=True).flatten().astype('float64')

emd_s = np.array([[emd_samples(cat1, cat1, bins="fd"), emd_samples(cat1, cat2, bins="fd"), emd_samples(cat1, shuttle, bins="fd")],
                  [emd_samples(cat2, cat1, bins="fd"), emd_samples(cat2, cat2, bins="fd"), emd_samples(cat2, shuttle, bins="fd")],
                  [emd_samples(shuttle, cat1, bins="fd"), emd_samples(shuttle, cat2, bins="fd"), emd_samples(shuttle, shuttle, bins="fd")]])

pmf_cat1, bins_cat1 = np.histogram(cat1 , bins="fd")
pmf_cat2, bins_cat2 = np.histogram(cat2 , bins="fd")
pmf_shuttle, bins_shuttle = np.histogram(shuttle , bins="fd")

emd_s2 = np.array([[emd_samples(pmf_cat1, pmf_cat1, bins="fd"), emd_samples(pmf_cat1, pmf_cat2, bins="fd"), emd_samples(pmf_cat1, pmf_shuttle, bins="fd")],
                  [emd_samples(pmf_cat2, pmf_cat1, bins="fd"), emd_samples(pmf_cat2, pmf_cat2, bins="fd"), emd_samples(pmf_cat2, pmf_shuttle, bins="fd")],
                  [emd_samples(pmf_shuttle, pmf_cat1, bins="fd"), emd_samples(pmf_shuttle, pmf_cat2, bins="fd"), emd_samples(pmf_shuttle, pmf_shuttle, bins="fd")]])

swd = np.array([[wasserstein_distance(pmf_cat1, pmf_cat1), wasserstein_distance(pmf_cat1, pmf_cat2), wasserstein_distance(pmf_cat1, pmf_shuttle)],
                [wasserstein_distance(pmf_cat2, pmf_cat1), wasserstein_distance(pmf_cat2, pmf_cat2), wasserstein_distance(pmf_cat2, pmf_shuttle)],
                [wasserstein_distance(pmf_shuttle, pmf_cat1), wasserstein_distance(pmf_shuttle, pmf_cat2), wasserstein_distance(pmf_shuttle, pmf_shuttle)]])

swd2 = np.array([[wasserstein_distance(cat1, cat1), wasserstein_distance(cat1, cat2), wasserstein_distance(cat1, shuttle)],
                [wasserstein_distance(cat2, cat1), wasserstein_distance(cat2, cat2), wasserstein_distance(cat2, shuttle)],
                [wasserstein_distance(shuttle, cat1), wasserstein_distance(shuttle, cat2), wasserstein_distance(shuttle, shuttle)]])

上面的示例对emd_sswd2产生了相似的结果,而对于emd_s2swd则得到了类似的结果,尽管最后一对仍然是完全不同的,因为在这种情况下,emd_samples应该根据直方图生成一个直方图。

EN

回答 1

Stack Overflow用户

发布于 2018-11-07 17:27:38

我遇到了一个类似的问题,我想在这里注意几件事。

  1. 函数emd_sampleswasserstein_distance都将在(经验)分布中观察到的值作为输入而不是分布本身。
  2. 函数emd允许您传递发行版,但是您需要提供度量作为附加参数。此外,当使用作为(密度)分布的直方图时,您需要将它们规范化。
  3. 不使灰度图像变平,就意味着您要比较只适用于pyemd的2D组分图。

示例用法:

代码语言:javascript
复制
import numpy as np
import skimage
import os

from pyemd import emd, emd_samples
from scipy.stats import wasserstein_distance

# get some test images
img1 = skimage.io.imread(os.path.join(skimage.data_dir, 'astronaut.png'))
img2 = skimage.io.imread(os.path.join(skimage.data_dir, 'camera.png'))
img3 = skimage.io.imread(os.path.join(skimage.data_dir, 'horse.png'))

# flatten them
images = [img.ravel() for img in [img1, img2, img3]]

# compute EMD using values
emd_samples(images[0], images[1]) # 25.57794401220945
wasserstein_distance(images[0], images[1]) # 25.76187896728515

# compute EMD using distributions
N_BINS = 256
hists = [np.histogram(img, N_BINS, density=True)[0].astype(np.float64) for img in images]

mgrid = np.meshgrid(np.arange(N_BINS), np.arange(N_BINS))
metric = np.abs(mgrid[0] - mgrid[1]).astype(np.float64)

emd(hists[0], hists[1], metric) # 25.862491463680065
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49234682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档