我有两个相等大小的图像,我想计算一个函数,让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[0])):
result[i,j] = f(patches1[i], patches1[j])
但这太慢了!!!
我想知道快速计算它并摆脱循环的最佳方法是什么。
谢谢
EDIT1:
f的实现是
def f (patch1, patch2):
return np.sqrt(patch1^2 + patch2^2)
答案 0 :(得分:0)
您可以使用多重处理使其快速:
#include <iostream>
#include <sstream>
#include <bitset>
#include <vector>
#include <iomanip>
#include <cstring>
#include <openssl/des.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main(int argc, char* argv[])
{
DES_cblock cb1 = { 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE };
DES_cblock cb2 = { 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE };
DES_cblock cb3 = { 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE };
DES_cblock cblock = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
DES_key_schedule ks1,ks2,ks3;
char string[] = "I am a software developer";
// ---------------------------------------------
// I use sizeof instead of strlen because I want
// to count the '\0' at the end, strlen would
// not count it
int stringLen(sizeof(string));
printf("Plain Text : %s\n",string);
char* cipher(new char[32]);
char* text(new char[stringLen]);
memset(cipher,0,32);
memset(text,0,stringLen);
DES_set_odd_parity(&cblock);
if (DES_set_key_checked(&cb1, &ks1) ||
DES_set_key_checked(&cb2, &ks2) ||
DES_set_key_checked(&cb3, &ks3)) {
printf("Key error, exiting ....\n");
return 1;
}
DES_ede3_cbc_encrypt((const unsigned char*)string,
(unsigned char*)cipher,
stringLen, &ks1, &ks2, &ks3,
&cblock, DES_ENCRYPT);
printf("Encrypted : %32.32s\n",cipher);
//-----------------------------------------------
// You need to start with the same cblock value
memset(cblock,0,sizeof(DES_cblock));
DES_set_odd_parity(&cblock);
//-----------------------------------------------
// I think you need to use 32 for the cipher len.
// You can't use strlen(cipher) because if there
// is a 0x00 in the middle of the cipher strlen
// will stop there and the length would be short
DES_ede3_cbc_encrypt((const unsigned char*)cipher,
(unsigned char*)text,
32, &ks1, &ks2, &ks3,
&cblock,DES_DECRYPT);
printf("Decrypted : %s\n",text);
return 0;
}
通过优化f使之在整个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))
而非image
上运行,可能有一种更聪明的方法。在这里,我仅显示一种工程方法。
答案 1 :(得分:0)
我对此进行了尝试-欢迎任何想对其代码进行基准测试的人复制我的初始化代码。基本上,它会创建一个标准化的图像,并将图像的黑色部分作为补丁A与白色部分作为补丁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)