parent
d83e36d227
commit
2ebd56523f
@ -1,2 +1,4 @@
|
||||
# patchMatch
|
||||
|
||||
cette branche a pour seul but de versioner et sauvgarder des experimentations.
|
||||
Elle ne rejoindra jamais la branche ```master```
|
@ -0,0 +1,59 @@
|
||||
from matplotlib.widgets import RectangleSelector
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
def doPatchMatch(img,x1,y1,x2,y2,patchSize=20):
|
||||
|
||||
def getRandomPatch():
|
||||
rx = np.random.randint(0, width - patchSize)
|
||||
ry = np.random.randint(0, height - patchSize)
|
||||
return rx, ry
|
||||
|
||||
|
||||
|
||||
semiPatch = int(patchSize/2)
|
||||
height, width, _ = img.shape
|
||||
xx1 = max(0, x1-semiPatch)
|
||||
yy1 = max(0, y1-semiPatch)
|
||||
xx2 = min(width, x2+semiPatch)
|
||||
yy2 = min(height, y2+semiPatch)
|
||||
|
||||
if (xx2-xx1 < patchSize or yy2-yy1 < patchSize):
|
||||
return img
|
||||
|
||||
|
||||
return img
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
img = plt.imread('boat.png')
|
||||
|
||||
if len(img.shape) == 2:
|
||||
img = np.stack((img,)*3, axis=-1)
|
||||
|
||||
def onselect(eclick, erelease):
|
||||
x1, y1 = eclick.xdata, eclick.ydata
|
||||
x2, y2 = erelease.xdata, erelease.ydata
|
||||
|
||||
print("drawing")
|
||||
img_copy = np.copy(img)
|
||||
#res = doKnn(img_copy,int(x1),int(y1),int(x2),int(y2))
|
||||
ax.imshow(img_copy)
|
||||
plt.draw()
|
||||
print("drawed")
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(img)
|
||||
toggle_selector = RectangleSelector(ax, onselect, useblit=True,
|
||||
button=[1], minspanx=5, minspany=5, spancoords='pixels',
|
||||
interactive=True)
|
||||
plt.axis('off')
|
||||
plt.show()
|
@ -0,0 +1,133 @@
|
||||
# j'ai trouvé ce code sur la page github:
|
||||
# https://github.com/MingtaoGuo/PatchMatch/blob/master/PatchMatch.py
|
||||
# pour experimenter et comprendre comment l'algoritme marche
|
||||
|
||||
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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("./cup_a.jpg"))
|
||||
ref = np.array(Image.open("./cup_b.jpg"))
|
||||
p_size = 3
|
||||
itr = 5
|
||||
start = time.time()
|
||||
f = NNS(img, ref, p_size, itr)
|
||||
end = time.time()
|
||||
print(end - start)
|
||||
reconstruction(f, img, ref)
|
Loading…
Reference in new issue