PATCHMATCH演算法解析

2021-10-24 03:58:22 字數 4679 閱讀 8137

**複雜度o(m*m*t*logm),m為影象的畫素個數,m為patch size ,t為迭代次數

import numpy as np

from pil import image

import time

def cal_distance(a, b, a_padding, b, p_size):

p = p_size // 2

patch_a = a_padding[a[0]:a[0]+p_size, a[1]:a[1]+p_size, :]

patch_b = b[b[0]-p:b[0]+p+1, b[1]-p:b[1]+p+1, :]

temp = patch_b - patch_a

num = np.sum(1 - np.int32(np.isnan(temp)))

dist = np.sum(np.square(np.nan_to_num(temp))) / num

return dist

def reconstruction(f, a, b):

a_h = np.size(a, 0)

a_w = np.size(a, 1)

temp = np.zeros_like(a)

for i in range(a_h):

for j in range(a_w):

temp[i, j, :] = b[f[i, j][0], f[i, j][1], :]

image.fromarray(temp).show()

def initialization(a, b, p_size):

a_h = np.size(a, 0)

a_w = np.size(a, 1)

b_h = np.size(b, 0)

b_w = np.size(b, 1)

p = p_size // 2

random_b_r = np.random.randint(p, b_h-p, [a_h, a_w])

random_b_c = np.random.randint(p, b_w-p, [a_h, a_w])

a_padding = np.ones([a_h+p*2, a_w+p*2, 3]) * np.nan

a_padding[p:a_h+p, p:a_w+p, :] = a

f = np.zeros([a_h, a_w], dtype=object)

dist = np.zeros([a_h, a_w])

for i in range(a_h):

for j in range(a_w):

a = np.array([i, j])

b = np.array([random_b_r[i, j], random_b_c[i, j]], dtype=np.int32)

f[i, j] = b

dist[i, j] = cal_distance(a, b, a_padding, b, p_size)

return f, dist, a_padding

def propagation(f, a, dist, a_padding, b, p_size, is_odd):

a_h = np.size(a_padding, 0) - p_size + 1

a_w = np.size(a_padding, 1) - p_size + 1

x = a[0]

y = a[1]

if is_odd:#向左上方傳播

d_left = dist[max(x-1, 0), y]

d_up = dist[x, max(y-1, 0)]

d_current = dist[x, y]

idx = np.argmin(np.array([d_current, d_left, d_up]))

if idx == 1:

f[x, y] = f[max(x - 1, 0), y]

dist[x, y] = cal_distance(a, f[x, y], a_padding, b, p_size)

if idx == 2:

f[x, y] = f[x, max(y - 1, 0)]

dist[x, y] = cal_distance(a, f[x, y], a_padding, b, p_size)

else:#向右下方傳播

d_right = dist[min(x + 1, a_h-1), y]

d_down = dist[x, min(y + 1, a_w-1)]

d_current = dist[x, y]

idx = np.argmin(np.array([d_current, d_right, d_down]))

if idx == 1:

f[x, y] = f[min(x + 1, a_h-1), y]

dist[x, y] = cal_distance(a, f[x, y], a_padding, b, p_size)

if idx == 2:

f[x, y] = f[x, min(y + 1, a_w-1)]

dist[x, y] = cal_distance(a, f[x, y], a_padding, b, p_size)

def random_search(f, a, dist, a_padding, b, p_size, alpha=0.5):

x = a[0]

y = a[1]

b_h = np.size(b, 0)

b_w = np.size(b, 1)

p = p_size // 2

i = 4

search_h = b_h * alpha ** i

search_w = b_w * alpha ** i

b_x = f[x, y][0]

b_y = f[x, y][1]

while search_h > 1 and search_w > 1:

search_min_r = max(b_x - search_h, p)

search_max_r = min(b_x + search_h, b_h-p)#不能越界

random_b_x = np.random.randint(search_min_r, search_max_r)#row

search_min_c = max(b_y - search_w, p)

search_max_c = min(b_y + search_w, b_w - p)

random_b_y = np.random.randint(search_min_c, search_max_c)#col

search_h = b_h * alpha ** i#用類似於二分法的方式不斷縮小搜尋範圍

search_w = b_w * alpha ** i

b = np.array([random_b_x, random_b_y])

d = cal_distance(a, b, a_padding, b, p_size)

if d < dist[x, y]:#如果新的隨機距離小於已有的距離,那麼就更新

dist[x, y] = d

f[x, y] = b

i += 1

def nns(img, ref, p_size, itr):

a_h = np.size(img, 0)

a_w = np.size(img, 1)

f, dist, img_padding = initialization(img, ref, p_size)#隨機初始化a到b的匹配

for itr in range(1, itr+1):

if itr % 2 == 0:

for i in range(a_h - 1, -1, -1):

for j in range(a_w - 1, -1, -1):

a = np.array([i, j])

propagation(f, a, dist, img_padding, ref, p_size, false)#先根據周圍畫素的匹配情況來進行本畫素的匹配

random_search(f, a, dist, img_padding, ref, p_size)#繼續進行大範圍的搜尋

else:

for i in range(a_h):

for j in range(a_w):

a = np.array([i, j])

propagation(f, a, dist, img_padding, ref, p_size, true)

random_search(f, a, dist, img_padding, ref, p_size)

print("iteration: %d"%(itr))

return f

if __name__ == "__main__":

img = np.array(image.open("001_0.png"))

ref = np.array(image.open("001_5.png"))

p_size = 3#patch的長寬

itr = 5#迭代次數

start = time.time()

f = nns(img, ref, p_size, itr)

end = time.time()

print(end - start)

reconstruction(f, img, ref)

DUKPT演算法解析

dukpt derived unique key per transaction 1 是什麼?是一種非常安全的金鑰管理技術,主要應用於對稱金鑰加密mac,pin等安全資料方面 2 主要思想 保證每一次交易流程使用唯一的金鑰,採用一種不可逆的金鑰轉換演算法,使得無法從當前交易資料資訊破解上一次交易金鑰...

KMP演算法解析

日期 2013年5月 1日 字串匹配是計算機的基本任務之一。舉例來說,有乙個字串 bbc abcdab abcdabcdabde 我想知道,裡面是否包含另乙個字串 abcdabd 許多演算法可以完成這個任務,knuth morris pratt演算法 簡稱kmp 是最常用的之一。它以三個發明者命名,...

highestOneBit 演算法解析

integer類有個highestonebit 方法,作用是返回具有單個 1 位的 int 值,在指定值中最高位的 1 位的位置,比如5 00000101 返回4 00000100 highestonebit 的演算法如下 public static inthighestonebit int i 為...