簡體   English   中英

如何比較兩個輪廓路徑在視覺上是否相似--Python / Matplotlib

[英]How to compare if two contour paths are visually similar - Python / Matplotlib

我想知道如果兩個路徑的輪廓重疊,如果它們是相似的,如何比較。

更具體地說,我有一組n個實現,每個實現都有它的輪廓級別。 我需要在l級驗證每個輪廓的穩定性。 要做到這一點,我必須計算它通過偶像發生了多少次。

到目前為止,我正在研究這段代碼:

def iso_contours(scalar_fields):

    #TODO : access the paths by level (0, 1, 2 ...)
    default = 0
    contours = {}
    contours_number = 0
    for scalar_field in scalar_fields:
        cs = plt.contour(scalar_field)
        for collection in cs.collections:
            paths = collection.get_paths()
            for path in paths:
                num = contours.get(path, default)
                contours[path] = num + 1
                contours_number += 1

    contours.update((x, y/float(contours_number)) for x, y in contours.items())
    return contours

然而,即使有兩條相同的路徑,它們也被視為不同的路徑。

所以, 我想知道如果給出兩條路徑,我可以確定它們是否在視覺上相似 正如@unutbu提醒我的那樣,我不能只比較頂點,因為頂點可能有不同的順序,或者一條路徑可能有1000個頂點而另一條路徑可能有100個頂點...

首先,我假設你知道你的輪廓被繪制成相同的比例並且沒有被翻譯,所以這不是圖像匹配的問題,而是試圖找到兩個笨拙形狀之間的差異。

有幾種方法可以做到這一點,兩者都應該給出大致相同的結果。 最准確的方法是在兩條曲線之間取內積,但這需要將曲線對齊並將其描述為相同的分辨率。 例如,這可以通過插值來完成,但這是一個非常麻煩的事情。

我在這里嘗試的方法是一個捷徑,但它應該給出一個合理的估計,即繪制兩條曲線之間的區域,並從圖中求和這個區域。 面積越小,曲線越相似。 (也就是說,總的來說,你使用內部產品的曲線,你使用的圖像就是區別的區域)。

例如,從這些輪廓開始:

在此輸入圖像描述

我們以這個情節結束,差異是標題中的總和:

在此輸入圖像描述

這是代碼(它有點復雜,因為我認為沒有辦法簡單地填充兩個任意參數化曲線,所以我從每個填充的單個輪廓中制作圖像,然后減去它們):

import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import matplotlib.cm as cm
import numpy as np
import io
import Image

xmin, xmax, ymin, ymax = -3, 6, -2, 3
delta = 0.025
x = np.arange(xmin, xmax, delta)
y = np.arange(ymin, ymax, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)

def f(a, b):
    return 10.*(a*Z2 - b*Z1)

def fill_contour(cs):
    v = cs.collections[0].get_paths()[0].vertices
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.fill(v[:,0], v[:,1], 'k')
    ax.set_xlim(xmin, xmax)
    ax.set_ylim(ymin, ymax)
    buf = io.BytesIO()
    fig.savefig(buf, format = 'png')
    buf.seek(0)
    im = Image.open(buf).convert('L')
    r = np.asarray(im).astype(np.int)
    r/=max(r.flat)
    return r

figc = plt.figure()
axc = figc.add_subplot(111)
c0 = .07
cs1 = axc.contour(X, Y, f(.6 ,.7), [c0], colors='r')
cs2 = axc.contour(X, Y, f(.8, 1.2), [c0], colors='g')


figd = plt.figure()
axd = figd.add_subplot(111)
d1 = fill_contour(cs1)
d2 = fill_contour(cs2)
d = abs(d1-d2)
im = axd.imshow(d, cmap=cm.gray)
figd.colorbar(im)
axd.set_title( "sum = %i" % np.sum(d.flat))

figc.show()
figd.show()

添加:

ax.set_position([0, 0, 1, 1])
ax.axis('off')

fill_contour()回調將改善結果,因為軸和“死”空間從收集的數據中刪除: fig.savefig(buf, format = 'png') 我試圖使用這種方法得到兩個輪廓或contourf的重疊區域,通過做d = abs(d1+d2)代替,但我不高興因為我丟失了X和Y信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM