I have two equal sized images and I want to compute a function lets suppose f on the patches of the images and calculate one number at each image location
The patch extraction is easy
patches1 = image.extract_patches_2d(img1,(5,5))
patches2 = image.extract_patches_2d(img2,(5,5))
Now applying the function could be something like as follows
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])
But this is very slow!!!
I am wondering that what could be the best possible way to calculate it fast and get rid of the loops.
Thanks
EDIT1:
The implementation of f is
def f (patch1, patch2):
return np.sqrt(patch1^2 + patch2^2)
You can make it fast using multiprocessing:
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))
There may be a smarter way to do this by optimizing f to work on whole image
instead of patches1
. Here I show an engineering way only.
I had a try at this - anyone wanting to benchmark their code is welcome to copy my initialisation. Basically it creates a single standardised image and compares the black part of the image as patch A with the white part as patch B.
#!/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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.