gpt4 book ai didi

python - 在matplotlib中用许多补丁绘制多个图像的有效方法?

转载 作者:行者123 更新时间:2023-12-03 17:53:31 26 4
gpt4 key购买 nike

我正在编写代码来显示图像之间的特征匹配。目前代码运行速度相当慢。我对如何加快速度有一些想法,但我对 matplotlib 或它在幕后的工作方式还不是 100% 满意。

代码的基本结构是:(我省略了一些内容以使其更具可读性)

from matplotlib.patches import Rectangle, Circle, Ellipse
import matplotlib.gridspec as gridspec
from matplotlib.transforms import Affine2D
from scipy.linalg import inv, sqrtm
import matplotlib.pyplot as plt
import numpy as np
  • 添加列表图像。每个图像都有自己的轴:ax,并记住 ax.transData
    gs = gridspec.GridSpec( nr, nc )
    for i in range(num_images):
    dm.ax_list[i] = plt.subplot(gs[i])
    dm.ax_list[i].imshow( img_list[i])
    transData_list[i] = dm.ax_list[i].transData
  • 将特征表示可视化为椭圆
    for i in range(num_chips):
    axi = chips[i].axi
    ax = dm.ax_list[axi]
    transData = dm.transData_list[axi]
    chip_feats = chips[i].features
    for feat in chip_feats:
    (x,y,a,c,d) = feat
    A = numpy.array( [ ( a, 0, 0 ) ,
    ( c, d, 0 ) ,
    ( 0, 0, 1 ) ] , dtype=np.float64)
    EllShape = Affine2D( numpy.array(sqrtm( inv(A) ), dtype=np.float64) )
    transEll = EllShape.translate(x,y)
    unitCirc = Circle((0,0),1,transform=transEll+transData)
    ax.add_patch(unitCirc)

  • 我已经使用 RunSnakeRun 来分析代码,我真正从中收集到的是,绘制所有内容需要很长时间。当我了解 matplotlib 中的转换时,我的基本想法是在每个图像自己的坐标中绘制每个图像,然后维护几个转换,以便我以后可以用它们做很酷的事情,但我怀疑它不会很好地缩放。

    抽奖的实际输出如下所示:



    当我调整它的大小时,这个数字大约需要 4 秒才能重绘,我将想要平移/缩放。

    我为每个特征添加了两个补丁,大约(每个图像 300 个特征)所以我可以看到轮廓和一些透明度。所以,显然有开销。但即使没有任何椭圆,它也相对较慢。

    我还需要编写一些代码来在匹配的特征之间放置线,但现在我不太确定使用多个轴是一个很好的主意,尤其是当这是一个相对较小的数据集时。

    因此,对于更具体的问题:
  • 绘制椭圆与变换圆是否更有效?使用 matplotlib 转换的开销是多少?
  • 有没有办法组合一组补丁,以便它们一起转换或更有效地转换?
  • 将所有内容打包到一个轴中会更有效吗?如果我这样做,转换范式还可以使用吗?或者变换是这里的罪魁祸首?
  • 有没有一种快速的方法可以在矩阵 A 的列表上执行 sqrtm( inv( A ) ) ?或者我将它们放在 for 循环中也一样好?
  • 我应该切换到 pyqtgraph 之类的东西吗?我不打算让它们成为平移和缩放之外的任何动画。 (也许将来我想将这些嵌入到交互式图表中)


  • 编辑:

    我已经能够通过手工计算平方根倒矩阵的形式来提高绘图效率。它的速度也相当大。

    在上面的代码中:
     A = numpy.array( [ ( a, 0, 0 ) ,
    ( c, d, 0 ) ,
    ( 0, 0, 1 ) ] , dtype=np.float64)
    EllShape = Affine2D( numpy.array(sqrtm( inv(A) ), dtype=np.float64) )

    被替换为
     EllShape = Affine2D([\
    ( 1/sqrt(a), 0, 0),\
    ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0),\
    ( 0, 0, 1)])

    我也发现了一些有趣的计时结果:
      num_to_run = 100000
    all_setup = ''' import numpy as np ; from scipy.linalg import sqrtm ; from numpy.linalg import inv ; from numpy import sqrt
    a=.1 ; c=43.2 ; d=32.343'''

    timeit( \
    'sqrtm(inv(np.array([ ( a, 0, 0 ) , ( c, d, 0 ) , ( 0, 0, 1 ) ])))',\
    setup=all_setup, number=num_to_run)
    >> 22.2588094075 #(Matlab reports 8 seconds for this run)

    timeit(\
    '[ (1/sqrt(a), 0, 0), ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0), (0, 0, 1) ]',\
    setup=all_setup, number=num_to_run)
    >> 1.10265190941 #(Matlab reports .1 seconds for this run)

    编辑 2

    我已经使用 PatchCollection 和一些手动计算非常快速地计算和绘制椭圆(大约一秒钟,我没有分析它)。
    唯一的缺点是我似乎无法将椭圆的填充设置为 false
     from matplotlib.collections import PatchCollection
    ell_list = []
    for i in range(num_chips):
    axi = chips[i].axi
    ax = dm.ax_list[axi]
    transData = dm.transData_list[axi]
    chip_feats = chips[i].features
    for feat in chip_feats:
    (x,y,a,c,d) = feat
    EllShape = Affine2D([\
    ( 1/sqrt(a), 0, x),\
    ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), y),\
    ( 0, 0, 1)])
    unitCirc = Circle((0,0),1,transform=EllShape)
    ell_list = [unitCirc] + ell_list
    ellipses = PatchCollection(ell_list)
    ellipses.set_color([1,1,1])
    ellipses.face_color('none') #'none' gives no fill, while None will default to [0,0,1]
    ellipses.set_alpha(.05)
    ellipses.set_transformation(transData)
    ax.add_collection(ellipses)

    最佳答案

    我已经能够通过手工计算平方根倒矩阵的形式来提高绘图效率。它的速度也相当大。

    在上面的代码中:

     A = numpy.array( [ ( a, 0, 0 ) ,
    ( c, d, 0 ) ,
    ( 0, 0, 1 ) ] , dtype=np.float64)
    EllShape = Affine2D( numpy.array(sqrtm( inv(A) ), dtype=np.float64) )

    被替换为
     EllShape = Affine2D([\
    ( 1/sqrt(a), 0, 0),\
    ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0),\
    ( 0, 0, 1)])

    我也发现了一些有趣的计时结果:
      num_to_run = 100000
    all_setup = ''' import numpy as np ; from scipy.linalg import sqrtm ; from numpy.linalg import inv ; from numpy import sqrt
    a=.1 ; c=43.2 ; d=32.343'''

    timeit( \
    'sqrtm(inv(np.array([ ( a, 0, 0 ) , ( c, d, 0 ) , ( 0, 0, 1 ) ])))',\
    setup=all_setup, number=num_to_run)
    >> 22.2588094075 #(Matlab reports 8 seconds for this run)

    timeit(\
    '[ (1/sqrt(a), 0, 0), ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0), (0, 0, 1) ]',\
    setup=all_setup, number=num_to_run)
    >> 1.10265190941 #(Matlab reports .1 seconds for this run)

    编辑 2

    我已经使用 PatchCollection 和一些手动计算非常快速地计算和绘制椭圆(大约一秒钟,我没有分析它)。
    唯一的缺点是我似乎无法将椭圆的填充设置为 false
     from matplotlib.collections import PatchCollection
    ell_list = []
    for i in range(num_chips):
    axi = chips[i].axi
    ax = dm.ax_list[axi]
    transData = dm.transData_list[axi]
    chip_feats = chips[i].features
    for feat in chip_feats:
    (x,y,a,c,d) = feat
    EllShape = Affine2D([\
    ( 1/sqrt(a), 0, x),\
    ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), y),\
    ( 0, 0, 1)])
    unitCirc = Circle((0,0),1,transform=EllShape)
    ell_list = [unitCirc] + ell_list
    ellipses = PatchCollection(ell_list)
    ellipses.set_color([1,1,1])
    ellipses.face_color('none') #'none' gives no fill, while None will default to [0,0,1]
    ellipses.set_alpha(.05)
    ellipses.set_transformation(transData)
    ax.add_collection(ellipses)

    关于python - 在matplotlib中用许多补丁绘制多个图像的有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15031136/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com