Самый быстрый способ вычислить функцию на патчи двух изображений - PullRequest
0 голосов
/ 31 мая 2019

У меня есть два изображения одинакового размера, и я хочу вычислить функцию, которая позволяет предположить f на участках изображений и рассчитать одно число в каждом месте изображения

Простое извлечение патчей

   patches1 = image.extract_patches_2d(img1,(5,5))
   patches2 = image.extract_patches_2d(img2,(5,5))

Теперь применение функции может выглядеть примерно так:

   result = numpy.zeros((image1.shape[0], img1.shape[1]))
   for i in range(len(image1.shape[0])):
       for j in range(len(image1.shape[1])):
           result[i,j] = f(patches1[i], patches1[j])

Но это очень медленно !!!

Мне интересно, что может быть лучшим способом для ее вычисления?быстро и избавиться от петель.

Спасибо

EDIT1:

Реализация f -

    def f (patch1, patch2):
        return np.sqrt(patch1^2 + patch2^2)

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Я попробовал это сделать - любой, кто хочет протестировать свой код, может скопировать мою инициализацию.По сути, он создает единое стандартизированное изображение и сравнивает черную часть изображения в виде пятна A с белой частью в виде пятна B.

enter image description here

#!/usr/local/bin/python3

import numpy as np
import math

# Generate a standardised "random" array
shape=(768,1024)                                                                        
np.random.seed(42)                                                                      
img = np.random.randint(0,256,shape,dtype=np.uint8) 

def loopy(patch1,patch2): 
    """Version with loops"""
    h, w = patch1.shape[0], patch1.shape[1] 
    result = np.zeros((h, w), dtype=np.float) 
    for i in range(h): 
        for j in range(w): 
            p1 = float(patch1[i,j]) 
            p2 = float(patch2[i,j]) 
            result[i,j] = math.sqrt(p1*p1+p2*p2) 
    return result 

def me(patch1,patch2): 
    A = patch1.astype(np.float) * patch1.astype(np.float) 
    B = patch2.astype(np.float) * patch2.astype(np.float)  
    return np.sqrt(A + B) 

# Run loopy and me and compare results
l = loopy(img[100:200,100:200],img[400:500,400:500])  
m = me(img[100:200,100:200],img[400:500,400:500])                                                                            
print(np.mean(m-l))

%timeit loopy(img[100:200,100:200],img[400:500,400:500])
# 5.73 ms ± 74.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit me(img[100:200,100:200],img[400:500,400:500])
# 40.2 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
0 голосов
/ 31 мая 2019

Вы можете сделать это быстро, используя многопроцессорность:

from concurrent import futures
import itertools
import numpy as np

patches1 = image.extract_patches_2d(img1,(5,5))
H = image.shape[0]; W = image.shape[1]
results = np.zeros(H*W)
with futures.ProcessPoolExecutor(max_workers=8) as exe:
    procs = {exe.submit(f, patches1[i], patches1[j]): i*W+j for (i,j) in itertools.product(range(H), range(W))}
    for r in futures.as_completed(procs):
        ids = procs[r]
        val = r.result()
        results[ids] = val
results = np.reshape(results,(H,W))

Может быть более разумный способ сделать это, оптимизировав f для работы на целых image вместо patches1.Здесь я показываю только инженерный путь.

...