【问题标题】:Shadow Removal in Python OpenCVPython OpenCV 中的阴影去除
【发布时间】:2018-05-24 12:57:47
【问题描述】:

我正在尝试使用 Finlayson 等人的熵最小化方法在 python OpenCV 中实现阴影去除。人:

“熵最小化的内在图像”,Finlayson 等。人。

我似乎无法匹配论文中的结果。我的熵图与论文中的不匹配,并且我得到了错误的最小熵。

有什么想法吗? (根据要求,我有更多的源代码和论文)

#############
# 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(u.T)
    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, e.T), np.linalg.norm(e) )

    chi_theta = chi.dot(P_theta)
    rho_estim = chi_theta.dot(U.T)
    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()

输出:

【问题讨论】:

标签: python image opencv shadows


【解决方案1】:

Shadow Removal Using Illumination Invariant Image Formation (Ranaweera, Drew) 在结果和讨论下指出,JPEG 图像和 PNG 图像的结果因 JPEG 压缩而不同。因此,期望结果与“熵最小化的内在图像”(Finlayson 等人)显示的完全一样可能是不合理的。

我还注意到,您没有添加作者在其他论文中推荐的“额外光线”。

此外,在定义 rg_chrom 时,通道的顺序需要是 BGR 而不是像您使用的 RGB。

我正在努力实现这篇论文,所以您的代码对我非常有用。谢谢你

【讨论】:

  • 我现在有一个有效的实现。我一直在与该论文的作者通信。那里明确表示不希望将其发布到 GitHub。如果您打算这样做,请不要这样做。
  • 对不起,结果是傲慢、苛刻和完全错误的。请让我解释一下。非常感谢您查看我的帖子和我的代码!这绝对是重点:与世界分享以学习和成长。我也感谢您的反馈!你是绝对正确的。通过 FFT(或任何其他无损压缩)进行的 JPEG 压缩会从图像中删除重要数据,并且您不会得到正确的结果。额外的光线也很重要,您必须小心 BGR 与 RGB。
  • 我问你是否不会在 Github 上发帖的原因是因为 Dr.'s Finlayson 等。 al.,让学生必须在课程作业中实现代码。我想我会再次询问是否可以向 OpenCV 提交拉取请求以将他们的算法添加到库中,并确保给予他们信任。由于 Python 是开源的,我不认为有任何法律上阻止我们发布到 GitHub 的内容,但我这样做只是出于荣誉。让我看看我是否可以再次与他们取得联系。再次感谢@Shawn Mathew,祝你好运!
  • 碰巧,您这样做是为了 Udacity、另一门课程,还是为了个人启蒙?
  • @A.Hendry 感谢您让我知道。我正在为我正在从事的项目实施这个。在过去的两天里,我一直在查看他的论文,以弄清楚如何实施它。希望论文有更多的实施细节。希望您获得将代码添加到 opencv 存储库的许可。这对很多人来说都是非常有价值的,因为论文中显示的结果非常棒
猜你喜欢
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多