【实操】数据扩增:Retinex算法用于图像颜色恢复和对比度增强

简介: 【实操】数据扩增:Retinex算法用于图像颜色恢复和对比度增强

前言

  随着深度学习技术的发展,数据扩增已经成为了训练高质量模型的重要步骤之一。然而,传统的数据扩增方法往往不能完全满足需求,因此,研究人员开始探索更加高效和有效的数据扩增方法。本文将介绍一种基于retinex算法的数据扩增方法,该方法可以在不影响图像内容的前提下,提高图像的亮度、对比度和颜色饱和度等方面的表现,从而提高模型的训练效果。

retinex

  基于视网膜理论公式:图像=反射率 * 亮度,我们需要的是估计亮度函数。该技术适用于高动态范围图像增强、水下图像增强、雾天图像增强和弱光图像增强。

在这里我们以下图作为原图进行图像变换:

image.png

retinex_FM实现

ini

复制代码

def retinex_FM(img,iter=4):
    if len(img.shape)==2:
        img=img[...,None]
    ret=np.zeros(img.shape,dtype='uint8')
    def update_OP(x,y):
        nonlocal OP
        IP=OP.copy()
        if x>0 and y==0:
            IP[:-x,:]=OP[x:,:]+R[:-x,:]-R[x:,:]
        if x==0 and y>0:
            IP[:,y:]=OP[:,:-y]+R[:,y:]-R[:,:-y]
        if x<0 and y==0:
            IP[-x:,:]=OP[:x,:]+R[-x:,:]-R[:x,:]
        if x==0 and y<0:
            IP[:,:y]=OP[:,-y:]+R[:,:y]-R[:,-y:]
        IP[IP>maximum]=maximum
        OP=(OP+IP)/2
    for i in range(img.shape[-1]):
        R=np.log(img[...,i].astype('double')+1)
        maximum=np.max(R)
        OP=maximum*np.ones(R.shape)
        S=2**(int(np.log2(np.min(R.shape))-1))
        while abs(S)>=1: #iterations is slow
            for k in range(iter):
                update_OP(S,0)
                update_OP(0,S)
            S=int(-S/2)
        OP=np.exp(OP)
        mmin=np.min(OP)
        mmax=np.max(OP)
        ret[...,i]=(OP-mmin)/(mmax-mmin)*255
    return ret.squeeze()

image.png

retinex_SSR实现

ini

复制代码

def retinex_SSR(img,sigma):
    
    if len(img.shape)==2:
        img=img[...,None]
    ret=np.zeros(img.shape,dtype='uint8')
    for i in range(img.shape[-1]):
        channel=img[...,i].astype('double')
        S_log=np.log(channel+1)
        gaussian=gauss_blur(channel,sigma)
        #gaussian=cv2.filter2D(channel,-1,get_gauss_kernel(sigma)) #conv may be slow if size too big
        #gaussian=cv2.GaussianBlur(channel,(0,0),sigma) #always slower
        L_log=np.log(gaussian+1)
        r=S_log-L_log
        R=r #R=np.exp(r)?
        mmin=np.min(R)
        mmax=np.max(R)
        stretch=(R-mmin)/(mmax-mmin)*255 #linear stretch
        ret[...,i]=stretch
    return ret.squeeze()

image.png

retinex_MSR实现

ini

复制代码

def retinex_MSR(img,sigmas=[15,80,250],weights=None):
    '''r=∑(log(S)-log(S*G))w, MSR combines various SSR with different(or same) weights, 
       commonly we select 3 scales(sigma) and equal weights, (15,80,250) is a good 
       choice. If len(sigmas)=1, equal to SSR
    args:
       sigmas: a list
       weights: None or a list, it represents the weight for each SSR, their sum should 
          be 1, if None, the weights will be [1/t, 1/t, ..., 1/t], t=len(sigmas)
    '''
    if weights==None:
        weights=np.ones(len(sigmas))/len(sigmas)
    elif not abs(sum(weights)-1)<0.00001:
        raise ValueError('sum of weights must be 1!')
    ret=np.zeros(img.shape,dtype='uint8')
    if len(img.shape)==2:
        img=img[...,None]
    for i in range(img.shape[-1]):
        channel=img[...,i].astype('double')
        r=np.zeros_like(channel)
        for k,sigma in enumerate(sigmas):
            r+=(np.log(channel+1)-np.log(gauss_blur(channel,sigma,)+1))*weights[k]
        mmin=np.min(r)
        mmax=np.max(r)
        stretch=(r-mmin)/(mmax-mmin)*255
        ret[...,i]=stretch
    return ret.squeeze()

image.png

retinex_gimp实现

ini

复制代码

def retinex_gimp(img,sigmas=[12,80,250],dynamic=2):
    alpha=128
    gain=1
    offset=0
    img=img.astype('double')+1 #
    csum_log=np.log(np.sum(img,axis=2))
    msr=MultiScaleRetinex(img-1,sigmas) #-1
    r=gain*(np.log(alpha*img)-csum_log[...,None])*msr+offset
    mean=np.mean(r,axis=(0,1),keepdims=True)
    var=np.sqrt(np.sum((r-mean)**2,axis=(0,1),keepdims=True)/r[...,0].size)
    mmin=mean-dynamic*var
    mmax=mean+dynamic*var
    stretch=(r-mmin)/(mmax-mmin)*255
    stretch[stretch>255]=255
    stretch[stretch<0]=0
    return stretch.astype('uint8')

image.png

retinex_MSRCR实现

ini

复制代码

def retinex_MSRCR(img,sigmas=[12,80,250],s1=0.01,s2=0.01):
    alpha=125
    img=img.astype('double')+1 #
    csum_log=np.log(np.sum(img,axis=2))
    msr=MultiScaleRetinex(img-1,sigmas) #-1
    r=(np.log(alpha*img)-csum_log[...,None])*msr
    #beta=46;G=192;b=-30;r=G*(beta*r-b) #deprecated
    #mmin,mmax=np.min(r),np.max(r)
    #stretch=(r-mmin)/(mmax-mmin)*255 #linear stretch is unsatisfactory
    for i in range(r.shape[-1]):
        r[...,i]=simplest_color_balance(r[...,i],0.01,0.01)
    return r.astype('uint8')

image.png

retinex_MSRCP算法

ini

复制代码

def retinex_MSRCP(img,sigmas=[12,80,250],s1=0.01,s2=0.01):
    Int=np.sum(img,axis=2)/3
    Diffs=[]
    for sigma in sigmas:
        Diffs.append(np.log(Int+1)-np.log(gauss_blur(Int,sigma)+1))
    MSR=sum(Diffs)/3
    Int1=simplest_color_balance(MSR,s1,s2)
    B=np.max(img,axis=2)
    A=np.min(np.stack((255/(B+eps),Int1/(Int+eps)),axis=2),axis=-1)
    return (A[...,None]*img).astype('uint8')

image.png

cv2_heq实现

ini

复制代码

def cv2_heq(img,yuv=False):
    if len(img.shape)==2:
        img=img[...,None]
    if yuv:
        img=cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb)
    ret=img.copy()
    for i in range(img.shape[-1]):
        ret[...,i]=cv2.equalizeHist(img[...,i])
        if yuv:
            break
    if yuv:
        return cv2.cvtColor(ret,cv2.COLOR_YCrCb2BGR)
    return ret.squeeze()

image.png

retinex_AMSR算法

ini

复制代码

def retinex_AMSR(img,sigmas=[12,80,250]):
    img=img.astype('double')+1 #
    msr=MultiScaleRetinex(img-1,sigmas,flag=False) #
    y=0.05
    for i in range(msr.shape[-1]):
        v,c=np.unique((msr[...,i]*100).astype('int'),return_counts=True)
        sort_v_index=np.argsort(v)
        sort_v,sort_c=v[sort_v_index],c[sort_v_index] #plot hist
        zero_ind=np.where(sort_v==0)[0][0]
        zero_c=sort_c[zero_ind]
        #
        _=np.where(sort_c[:zero_ind]<=zero_c*y)[0]
        if len(_)==0:
            low_ind=0
        else:
            low_ind=_[-1]
        _=np.where(sort_c[zero_ind+1:]<=zero_c*y)[0]
        if len(_)==0:
            up_ind=len(sort_c)-1
        else:
            up_ind=_[0]+zero_ind+1
        #
        low_v,up_v=sort_v[[low_ind,up_ind]]/100 #low clip value and up clip value
        msr[...,i]=np.maximum(np.minimum(msr[:,:,i],up_v),low_v)
        mmin=np.min(msr[...,i])
        mmax=np.max(msr[...,i])
        msr[...,i]=(msr[...,i]-mmin)/(mmax-mmin)*255
    msr=msr.astype('uint8')
    return msr

image.png

结尾

  Retinex算法在数据扩增领域的应用是十分广泛的。通过对图像的处理,我们可以得到更加清晰、明亮、自然的图像,从而提升了机器学习模型的准确度和稳定性。而且,Retinex算法的优点在于可以针对不同的图像进行不同的处理,满足了数据扩增的个性化需求。因此,在进行图像数据扩增时,Retinex算法是一种十分有效的方法,值得我们深入研究和应用。


相关文章
|
3天前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
【7月更文挑战第12天】归并排序是高效稳定的排序算法,采用分治策略。Python 实现包括递归地分割数组及合并已排序部分。示例代码展示了如何将 `[12, 11, 13, 5, 6]` 分割并归并成有序数组 `[5, 6, 11, 12, 13]`。虽然 $O(n log n)$ 时间复杂度优秀,但需额外空间,适合大规模数据排序。对于小规模数据,可考虑其他算法。**
15 4
|
27天前
|
机器学习/深度学习 人工智能 算法
【CVPR2024】面向StableDiffusion的编辑算法FreePromptEditing,提升图像编辑效果
近日,阿里云人工智能平台PAI与华南理工大学贾奎教授团队合作在深度学习顶级会议 CVPR2024 上发表 FPE(Free-Prompt-Editing) 算法,这是一种面向StableDiffusion的图像编辑算法。在这篇论文中,StableDiffusion可用于实现图像编辑的本质被挖掘,解释证明了基于StableDiffusion编辑的算法本质,并基于此设计了新的图像编辑算法,大幅度提升了图像编辑的效率。
|
20天前
|
算法 计算机视觉
基于Chan-Vese算法的图像边缘提取matlab仿真
**算法预览展示了4幅图像,从边缘检测到最终分割,体现了在matlab2022a中应用的Chan-Vese水平集迭代过程。核心代码段用于更新水平集并显示迭代效果,最后生成分割结果及误差曲线。Chan-Vese模型(2001)是图像分割的经典方法,通过最小化能量函数自动检测平滑区域和清晰边界的图像分割,适用于复杂环境,广泛应用于医学影像和机器视觉。**
|
28天前
|
机器学习/深度学习 人工智能 自然语言处理
【CVPR2024】阿里云人工智能平台PAI图像编辑算法论文入选CVPR2024
近期,阿里云人工智能平台PAI发表的图像编辑算法论文在CVPR-2024上正式亮相发表。论文成果是阿里云与华南理工大学贾奎教授领衔的团队共同研发。此次入选标志着阿里云人工智能平台PAI自主研发的图像编辑算法达到了先进水平,赢得了国际学术界的认可。在阿里云人工智能平台PAI算法团队和华南理工大学的老师学生们一同的坚持和热情下,将阿里云在图像生成与编辑领域的先进理念得以通过学术论文和会议的形式,向业界传递和展现。
|
25天前
|
机器学习/深度学习 算法 数据可视化
m基于PSO-LSTM粒子群优化长短记忆网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,应用PSO优化的LSTM模型提升了电力负荷预测效果。优化前预测波动大,优化后预测更稳定。PSO借鉴群体智能,寻找LSTM超参数(如学习率、隐藏层大小)的最优组合,以最小化误差。LSTM通过门控机制处理序列数据。代码显示了模型训练、预测及误差可视化过程。经过优化,模型性能得到改善。
43 6
|
27天前
|
机器学习/深度学习 算法 Python
机器学习算法的比较与选择是在实际应用中非常重要的一步,不同的算法适用于不同的问题和数据特征。
机器学习算法的比较与选择是在实际应用中非常重要的一步,不同的算法适用于不同的问题和数据特征。
|
6天前
|
机器学习/深度学习 运维 算法
Python基于局部离群因子LOF算法(LocalOutlierFactor)实现信用卡数据异常值检测项目实战
Python基于局部离群因子LOF算法(LocalOutlierFactor)实现信用卡数据异常值检测项目实战
|
6天前
|
机器学习/深度学习 数据采集 运维
Python基于孤立森林算法(IsolationForest)实现数据异常值检测项目实战
Python基于孤立森林算法(IsolationForest)实现数据异常值检测项目实战
|
10天前
|
算法 安全 数据安全/隐私保护
支付系统---微信支付09------数字签名,现在Bob想要给Pink写一封信,信件的内容不需要加密,怎样能够保证信息的完整性,使用信息完整性的主要手段是摘要算法,散列函数,哈希函数,H称为数据指纹
支付系统---微信支付09------数字签名,现在Bob想要给Pink写一封信,信件的内容不需要加密,怎样能够保证信息的完整性,使用信息完整性的主要手段是摘要算法,散列函数,哈希函数,H称为数据指纹
|
24天前
|
机器学习/深度学习 算法 数据挖掘
机器学习之聚类——MeanShift算法和图像矢量量化
机器学习之聚类——MeanShift算法和图像矢量量化
20 0