【问题标题】:Finding the best matching block/patch in Python [closed]在 Python 中找到最佳匹配的块/补丁 [关闭]
【发布时间】:2014-08-08 20:36:44
【问题描述】:

我希望在以较大二维数组的位置 (x,y) 为中心的 WxW 窗口内找到最接近的匹配 NxN 块。下面的代码工作正常,但对我的需要来说非常慢,因为我需要多次运行此操作。有一个更好的方法吗?? 这里 N = 3, W = 15, x =15, y = 15 并且 (bestx,besty) 是最佳匹配块的中心

import numpy as np

## Generate some test data
CurPatch = np.random.randint(20, size=(3, 3))
Data = np.random.randint(20,size=(30,30))

# Current Location 
x,y = 15,15
# Initialise Best Match
bestcost = 999.0
bestx = 0;besty=0

for Wy in xrange(-7,8):
    for Wx in xrange(-7,8):
            Ywj,Ywi = y+Wy,x+Wx 

            cost = 0.0
            for py in xrange(3):
                for px in xrange(3):
                    cost += abs(Data[Ywj+py-1,Ywi+px-1] - CurPatch[py,px]) 

            if cost < bestcost:
                bestcost = cost
                besty,bestx = Ywj,Ywi

print besty,bestx

【问题讨论】:

  • 你可以检查cost是否大于或等于bestcost里面的for px in xrange(3):如果是的话你可以break,这样你可以节省很多不必要的迭代。
  • 这个问题似乎是题外话,因为它是关于改进工作代码,这个问题可能更适合 codereview.stackexchange.com

标签: python arrays window patch matching


【解决方案1】:

为了感受速度,使用 numpy 的 w 与大窗口大小相同的子问题更快(也更简洁):

a= '''import numpy as np


## Generate some test data
CurPatch = np.random.randint(20, size=(3, 3))
Data = np.random.randint(20,size=(30,30))


def best(CurPatch,Data):

    # Current Location 
    x,y = 15,15
    # Initialise Best Match
    bestcost = 999.0
    bestx = 0;besty=0

    for Wy in xrange(-14,14):
        for Wx in xrange(-14,14):
                Ywj,Ywi = y+Wy,x+Wx 

                cost = 0.0
                for py in xrange(3):
                    for px in xrange(3):
                        cost += (Data[Ywj+py-1,Ywi+px-1] - CurPatch[py,px])**2 

                if cost < bestcost:
                    bestcost = cost
                    besty,bestx = Ywj,Ywi
    return besty,bestx,bestcost



def minimize(CurPatch,W):
    max_sum=999
    s= CurPatch.shape[0]
    S= W.shape[0]
    for i in range(0,S-s):
        for j in range(0,S-s):
            running= np.sum(np.square((W[i:i+3,j:j+3]-CurPatch)))
            if running<max_sum:
                max_sum=running
                x=i+1;y=j+1
    return x,y,max_sum

'''


import timeit
print min(timeit.Timer('minimize(CurPatch,Data)', a).repeat(7, 10))
print min(timeit.Timer('best(CurPatch,Data)', a).repeat(7, 10))     

【讨论】:

    【解决方案2】:

    正如我在评论中所说,您可以检查cost 是否大于或等于bestcost 内的bestcost,如果是这样,您可以中断,这样您可以节省很多不必要的迭代

    示例(是否会改变灯光以强调更大迭代的差异):

    import numpy as np
    import time
    
    ## Generate some test data
    CurPatch = np.random.randint(100, size=(3, 3))
    Data = np.random.randint(100, size=(3000,3000))
    
    # Current Location 
    x,y = 10, 10
    # Initialise Best Match
    bestcost = 999.0
    bestx = 0;besty=0
    
    t0 = time.time()
    for Wy in xrange(-7,50):
        for Wx in xrange(-7,50):
                Ywj, Ywi = y+Wy, x+Wx
    
                cost = 0.0
                for py in xrange(3):
                    for px in xrange(3):
                        cost += abs(Data[Ywj+py-1,Ywi+px-1] - CurPatch[py,px])
                        if cost >= bestcost:
                            break
    
                if cost < bestcost:
                    bestcost = cost
                    besty,bestx = Ywj,Ywi
    
    print besty, bestx
    print "time: {}".format(time.time() - t0)
    

    时间为 26ms

    时间:0.0269999504089

    您的代码没有中断将输出 37 毫秒:

    时间:0.0379998683929

    另外我必须建议将此代码转换为函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多