├── README.md ├── algo-average.py ├── algo-cluster.py ├── algo-frpca.py └── algo-rpca.py /README.md: -------------------------------------------------------------------------------- 1 | # Image-Reflection-Removal 2 | 3 | There are 4 algorithm to remove relection from input images. 4 | 5 | Average, Robust PCA and Fixed Rank Robust PCA will solve this problem, 6 | 7 | K-means cluster is just a naive approach for this problem. 8 | -------------------------------------------------------------------------------- /algo-average.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import os 4 | 5 | files = [f for f in os.listdir('.') if os.path.isfile(f)] 6 | imgs = [] 7 | 8 | #read input 9 | for f in files: 10 | if 'png' in f and 'background' not in f: 11 | imgs.append(cv2.imread(f)) 12 | 13 | #generate output 14 | h, w = imgs[0].shape[:2] 15 | img_out = np.zeros((h, w, 3), np.uint8) 16 | num = len(imgs) 17 | 18 | for i in range(h): 19 | for j in range(w): 20 | r = g = b = 0 21 | 22 | for img in imgs: 23 | r = r + img[i, j][0] 24 | g = g + img[i, j][1] 25 | b = b + img[i, j][2] 26 | # print "original: ", img[i, j] 27 | 28 | img_out[i, j] = [r/num, g/num, b/num] 29 | # print "background: ", img_out[i, j] 30 | 31 | cv2.imwrite('backgroud_algo1.png', img_out) 32 | -------------------------------------------------------------------------------- /algo-cluster.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import os 4 | 5 | files = [f for f in os.listdir('.') if os.path.isfile(f)] 6 | imgs = [] 7 | 8 | #read input 9 | for f in files: 10 | if 'png' in f and 'background' not in f: 11 | imgs.append(cv2.imread(f)) 12 | 13 | #generate output 14 | h, w = imgs[0].shape[:2] 15 | img_out = np.zeros((h, w, 3), np.uint8) 16 | num = len(imgs) 17 | 18 | def main_cluster_mean(i, j): 19 | mat = np.empty([num, 3]) 20 | for index in range(num): 21 | mat[index,:] = imgs[index][i, j] 22 | mat = np.float32(mat) 23 | 24 | # define criteria and apply kmeans() 25 | criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.5) 26 | ret,label,center=cv2.kmeans(mat,2,criteria,20,cv2.KMEANS_PP_CENTERS) 27 | label = label.flatten() 28 | label_sort = np.bincount(label) 29 | main_cluster = np.argmax(label_sort) 30 | return np.round(center[main_cluster,:]) 31 | 32 | for i in range(h): 33 | for j in range(w): 34 | img_out[i, j] = main_cluster_mean(i, j) 35 | 36 | cv2.imwrite('backgroud_algo2.png', img_out) 37 | -------------------------------------------------------------------------------- /algo-frpca.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import numpy.linalg as la 4 | import os 5 | 6 | files = [f for f in os.listdir('.') if os.path.isfile(f)] 7 | imgs= [] 8 | 9 | # read input 10 | for f in files: 11 | if 'png' in f and 'reflection' not in f and 'background' not in f: 12 | imgs.append(cv2.imread(f)) 13 | elif 'noreflection' in f: 14 | noreflection = cv2.imread(f) 15 | 16 | # generate matrix for robust pca 17 | num = len(imgs) 18 | h, w = imgs[0].shape[:2] 19 | imgresh = np.zeros((h*w*3, num)) 20 | for index in range(num): 21 | imgresh[:, index] = np.reshape(imgs[index], (h*w*3)) 22 | 23 | def shrink(M, tau): 24 | return np.sign(M) * np.maximum((np.abs(M) - tau), np.zeros(M.shape)) 25 | 26 | def norm_p(M, p): 27 | return np.sum(np.power(M, p)) 28 | 29 | def svd_threshold(M, tau): 30 | U, S, V = np.linalg.svd(M, full_matrices=False) 31 | trim_S = shrink(S, tau) 32 | if la.matrix_rank(trim_S) < 1: 33 | return np.dot(U, np.dot(np.diag(trim_S), V)) 34 | else: 35 | Sr = np.zeros(S.shape) 36 | Sr[0] = S[0] 37 | return np.dot(U, np.dot(np.diag(Sr), V)) 38 | 39 | def compute_mu(D): 40 | return np.prod(D.shape) / (4 * norm_p(D, 2)) 41 | 42 | def Jfunction(X,lam): 43 | X = np.sign(X) 44 | U, S, V = la.svd(X, full_matrices=False) 45 | s_norm = np.max(S) 46 | i_norm = 1/lam*np.max(np.absolute(X)) 47 | return X/max(s_norm,i_norm) 48 | 49 | def robust_pca(D, max_iter=1000): 50 | iter = 0 51 | err = np.Inf 52 | S_temp = Sk = np.zeros(D.shape) 53 | L_temp = Lk = np.zeros(D.shape) 54 | 55 | mu = compute_mu(D) 56 | lmbda = 1 / np.sqrt(np.max(D.shape)) 57 | Yk = Jfunction(D, lmbda) 58 | 59 | tol = 1E-7 60 | tol_primal = 1E-5 61 | 62 | while (err > tol) and iter < max_iter: 63 | primal_converge = False 64 | primal_iter = 0 65 | print 'iter 1: ', iter 66 | Lk = svd_threshold(D - Sk + Yk/mu, 1/mu) 67 | Sk = shrink(D - Lk + Yk/mu, lmbda/mu) 68 | 69 | while (not primal_converge) and primal_iter < 100: 70 | print 'iter 2: ', primal_iter 71 | Lk = svd_threshold(D - Sk + Yk/mu, 1/mu) 72 | Sk = shrink(D - Lk + Yk/mu, lmbda/mu) 73 | print 'L norm: ', la.norm(L_temp - Lk) 74 | print 'S norm: ', la.norm(S_temp - Sk) 75 | if la.norm(L_temp - Lk) < tol_primal and la.norm(S_temp - Sk) < tol_primal: 76 | primal_converge = True 77 | S_temp = Sk 78 | L_temp = Lk 79 | primal_iter = primal_iter + 1 80 | 81 | Yk = Yk + mu * (D - Lk - Sk) 82 | mu = mu * 1.5 83 | err = la.norm(D - Lk - Sk) 84 | print 'Error is: ', err 85 | iter += 1 86 | 87 | return Lk, Sk 88 | 89 | L, S = robust_pca(imgresh) 90 | 91 | print L, S 92 | print L.shape, S.shape 93 | 94 | img_out = np.zeros(h*w*3) 95 | img_out2 = np.zeros(h*w*3) 96 | # generate output 97 | for index in range(num): 98 | img_out += L[:, index] 99 | img_out2 += S[:, index] 100 | 101 | img_out = np.reshape((img_out/num), (h, w, 3)) 102 | img_out2 = np.reshape(img_out2, (h, w, 3)) 103 | err = la.norm(img_out.astype("float") - noreflection.astype("float")) 104 | print err # 105 | cv2.imwrite('background_pca_frpca.png', img_out) 106 | cv2.imwrite('reflection_pca_frpca.png', img_out2) 107 | -------------------------------------------------------------------------------- /algo-rpca.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import numpy.linalg as la 4 | import os 5 | 6 | files = [f for f in os.listdir('.') if os.path.isfile(f)] 7 | imgs= [] 8 | 9 | # read input 10 | for f in files: 11 | if 'png' in f and 'reflection' not in f and 'background' not in f: 12 | imgs.append(cv2.imread(f)) 13 | elif 'noreflection' in f: 14 | noreflection = cv2.imread(f) 15 | 16 | # generate matrix for robust pca 17 | num = len(imgs) 18 | h, w = imgs[0].shape[:2] 19 | imgresh = np.zeros((h*w*3, num)) 20 | for index in range(num): 21 | imgresh[:, index] = np.reshape(imgs[index], (h*w*3)) 22 | 23 | def shrink(M, tau): 24 | return np.sign(M) * np.maximum((np.abs(M) - tau), np.zeros(M.shape)) 25 | 26 | def norm_p(M, p): 27 | return np.sum(np.power(M, p)) 28 | 29 | def svd_threshold(M, tau): 30 | U, S, V = np.linalg.svd(M, full_matrices=False) 31 | trim_S = shrink(S, tau) 32 | return np.dot(U, np.dot(np.diag(trim_S), V)) 33 | 34 | def compute_mu(D): 35 | return np.prod(D.shape) / (4 * norm_p(D, 2)) 36 | 37 | def Jfunction(X,lam): 38 | X = np.sign(X) 39 | U, S, V = la.svd(X, full_matrices=False) 40 | s_norm = np.max(S) 41 | i_norm = 1/lam*np.max(np.absolute(X)) 42 | return X/max(s_norm,i_norm) 43 | 44 | def robust_pca(D, max_iter=1000): 45 | iter = 0 46 | err = np.Inf 47 | S_temp = Sk = np.zeros(D.shape) 48 | L_temp = Lk = np.zeros(D.shape) 49 | 50 | mu = compute_mu(D) 51 | lmbda = 1 / np.sqrt(np.max(D.shape)) 52 | Yk = Jfunction(D, lmbda) 53 | 54 | tol = 1E-7 55 | tol_primal = 1E-5 56 | 57 | while (err > tol) and iter < max_iter: 58 | primal_converge = False 59 | primal_iter = 0 60 | print 'iter 1: ', iter 61 | Lk = svd_threshold(D - Sk + Yk/mu, 1/mu) 62 | Sk = shrink(D - Lk + Yk/mu, lmbda/mu) 63 | 64 | while (not primal_converge) and primal_iter < 100: 65 | print 'iter 2: ', primal_iter 66 | Lk = svd_threshold(D - Sk + Yk/mu, 1/mu) 67 | Sk = shrink(D - Lk + Yk/mu, lmbda/mu) 68 | print 'L norm: ', la.norm(L_temp - Lk) 69 | print 'S norm: ', la.norm(S_temp - Sk) 70 | if la.norm(L_temp - Lk) < tol_primal and la.norm(S_temp - Sk) < tol_primal: 71 | primal_converge = True 72 | S_temp = Sk 73 | L_temp = Lk 74 | primal_iter = primal_iter + 1 75 | 76 | Yk = Yk + mu * (D - Lk - Sk) 77 | mu = mu * 1.5 78 | err = la.norm(D - Lk - Sk) 79 | print 'Error is: ', err 80 | iter += 1 81 | 82 | return Lk, Sk 83 | 84 | L, S = robust_pca(imgresh) 85 | 86 | print L, S 87 | print L.shape, S.shape 88 | 89 | img_out = np.zeros(h*w*3) 90 | img_out2 = np.zeros(h*w*3) 91 | # generate output 92 | for index in range(num): 93 | img_out += L[:, index] 94 | img_out2 += S[:, index] 95 | 96 | img_out = np.reshape((img_out/num), (h, w, 3)) 97 | img_out2 = np.reshape(img_out2, (h, w, 3)) 98 | err = la.norm(img_out.astype("float") - noreflection.astype("float")) 99 | print err # 100 | cv2.imwrite('background_pca_frpca.png', img_out) 101 | cv2.imwrite('reflection_pca_frpca.png', img_out2) 102 | --------------------------------------------------------------------------------