diff --git a/README.md b/README.md index c6d355d..e77cf20 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # patchMatch +cette branche a pour seul but de versioner et sauvgarder des experimentations. +Elle ne rejoindra jamais la branche ```master``` \ No newline at end of file diff --git a/customPatchMatch.py b/customPatchMatch.py new file mode 100644 index 0000000..cf4a5d1 --- /dev/null +++ b/customPatchMatch.py @@ -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() diff --git a/exemple.py b/exemple.py new file mode 100644 index 0000000..135195b --- /dev/null +++ b/exemple.py @@ -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) \ No newline at end of file diff --git a/knn.py b/knn.py index 66bfac5..1b97f0e 100644 --- a/knn.py +++ b/knn.py @@ -72,7 +72,6 @@ if len(img.shape) == 2: def onselect(eclick, erelease): x1, y1 = eclick.xdata, eclick.ydata - x2 = x1 + 150 x2, y2 = erelease.xdata, erelease.ydata img_copy = np.copy(img)