Drop shadow in Python OpenCV

I am trying to implement shadow removal in python OpenCV using the entropy minimization method of Finlayson, et. Al :.

โ€œInner images by minimizing entropy,โ€ Finlayson, et. and etc.

It seems that I do not agree with the results of the work. My entropy plot does not match the data from the article, and I get the wrong minimum entropy.

Any thoughts? (I have much more source code and documents on request)

############# # LIBRARIES ############# import numpy as np import cv2 import os import sys import matplotlib.image as mpimg import matplotlib.pyplot as plt from PIL import Image import scipy from scipy.optimize import leastsq from scipy.stats.mstats import gmean from scipy.signal import argrelextrema from scipy.stats import entropy from scipy.signal import savgol_filter root = r'\path\to\my_folder' fl = r'my_file.jpg' ############# # PROGRAM ############# if __name__ == '__main__': #----------------------------------- ## 1. Create Chromaticity Vectors ## #----------------------------------- # Get Image img = cv2.imread(os.path.join(root, fl)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) h, w = img.shape[:2] plt.imshow(img) plt.title('Original') plt.show() img = cv2.GaussianBlur(img, (5,5), 0) # Separate Channels r, g, b = cv2.split(img) im_sum = np.sum(img, axis=2) im_mean = gmean(img, axis=2) # Create "normalized", mean, and rg chromaticity vectors # We use mean (works better than norm). rg Chromaticity is # for visualization n_r = np.ma.divide( 1.*r, g ) n_b = np.ma.divide( 1.*b, g ) mean_r = np.ma.divide(1.*r, im_mean) mean_g = np.ma.divide(1.*g, im_mean) mean_b = np.ma.divide(1.*b, im_mean) rg_chrom_r = np.ma.divide(1.*r, im_sum) rg_chrom_g = np.ma.divide(1.*g, im_sum) rg_chrom_b = np.ma.divide(1.*b, im_sum) # Visualize rg Chromaticity --> DEBUGGING rg_chrom = np.zeros_like(img) rg_chrom[:,:,0] = np.clip(np.uint8(rg_chrom_r*255), 0, 255) rg_chrom[:,:,1] = np.clip(np.uint8(rg_chrom_g*255), 0, 255) rg_chrom[:,:,2] = np.clip(np.uint8(rg_chrom_b*255), 0, 255) plt.imshow(rg_chrom) plt.title('rg Chromaticity') plt.show() #----------------------- ## 2. Take Logarithms ## #----------------------- l_rg = np.ma.log(n_r) l_bg = np.ma.log(n_b) log_r = np.ma.log(mean_r) log_g = np.ma.log(mean_g) log_b = np.ma.log(mean_b) ## rho = np.zeros_like(img, dtype=np.float64) ## ## rho[:,:,0] = log_r ## rho[:,:,1] = log_g ## rho[:,:,2] = log_b rho = cv2.merge((log_r, log_g, log_b)) # Visualize Logarithms --> DEBUGGING plt.scatter(l_rg, l_bg, s = 2) plt.xlabel('Log(R/G)') plt.ylabel('Log(B/G)') plt.title('Log Chromaticities') plt.show() plt.scatter(log_r, log_b, s = 2) plt.xlabel('Log( R / 3root(R*G*B) )') plt.ylabel('Log( B / 3root(R*G*B) )') plt.title('Geometric Mean Log Chromaticities') plt.show() #---------------------------- ## 3. Rotate through Theta ## #---------------------------- u = 1./np.sqrt(3)*np.array([[1,1,1]]).T I = np.eye(3) tol = 1e-15 P_u_norm = I - u.dot(uT) U_, s, V_ = np.linalg.svd(P_u_norm, full_matrices = False) s[ np.where( s <= tol ) ] = 0. U = np.dot(np.eye(3)*np.sqrt(s), V_) U = U[ ~np.all( U == 0, axis = 1) ].T # Columns are upside down and column 2 is negated...? U = U[::-1,:] U[:,1] *= -1. ## TRUE ARRAY: ## ## U = np.array([[ 0.70710678, 0.40824829], ## [-0.70710678, 0.40824829], ## [ 0. , -0.81649658]]) chi = rho.dot(U) # Visualize chi --> DEBUGGING plt.scatter(chi[:,:,0], chi[:,:,1], s = 2) plt.xlabel('chi1') plt.ylabel('chi2') plt.title('2D Log Chromaticities') plt.show() e = np.array([[np.cos(np.radians(np.linspace(1, 180, 180))), \ np.sin(np.radians(np.linspace(1, 180, 180)))]]) gs = chi.dot(e) prob = np.array([np.histogram(gs[...,i], bins='scott', density=True)[0] for i in range(np.size(gs, axis=3))]) eta = np.array([entropy(p, base=2) for p in prob]) plt.plot(eta) plt.xlabel('Angle (deg)') plt.ylabel('Entropy, eta') plt.title('Entropy Minimization') plt.show() theta_min = np.radians(np.argmin(eta)) print('Min Angle: ', np.degrees(theta_min)) e = np.array([[-1.*np.sin(theta_min)], [np.cos(theta_min)]]) gs_approx = chi.dot(e) # Visualize Grayscale Approximation --> DEBUGGING plt.imshow(gs_approx.squeeze(), cmap='gray') plt.title('Grayscale Approximation') plt.show() P_theta = np.ma.divide( np.dot(e, eT), np.linalg.norm(e) ) chi_theta = chi.dot(P_theta) rho_estim = chi_theta.dot(UT) mean_estim = np.ma.exp(rho_estim) estim = np.zeros_like(mean_estim, dtype=np.float64) estim[:,:,0] = np.divide(mean_estim[:,:,0], np.sum(mean_estim, axis=2)) estim[:,:,1] = np.divide(mean_estim[:,:,1], np.sum(mean_estim, axis=2)) estim[:,:,2] = np.divide(mean_estim[:,:,2], np.sum(mean_estim, axis=2)) plt.imshow(estim) plt.title('Invariant rg Chromaticity') plt.show() 

Output:

Original

rg Chromaticity

Chromatic Journal

Geometric Mean Logical Chronologies

2D geometric chronological logarithms

Entropy minimization

Grayscale Zoom

Invariant rg Chromaticity

+6
source share
3 answers

Matlab code for Shadow segmentation and remove this part of the application in the attached document. Hope this can help you. reference document

0
source

Removing the shadow using Invariant Imaging (Ranaweera, Drew) in the Results and Discussion section shows that the results of JPEG images and PNG images are different due to JPEG compression. Thus, expecting results in exactly the same way as โ€œInner images by minimizing entropyโ€ (Finlayson, et al.) May not be reasonable.

I also notice that you are not adding the extra light that the author recommends in other documents.

Also, when defining rg_chrom , the channel order should be BGR instead of RGB, as you used.

I am working on an article implementation, so your code was very useful to me. thanks for this

0
source

I also follow this article. but my main language is java, so there is no library like pynum, so I follow paper formulas exactly. I came here while I am looking for sample codes. In any case, do not you think that you should choose the "maximum" angle? he said that the minimum angle works for Shannon's entropy, and the maximum angle works for quadratic entropy. I hope that my mention will be useful even if it was written 1 year ago.

0
source

Source: https://habr.com/ru/post/1273966/


All Articles