【实操】数据扩增: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算法是一种十分有效的方法,值得我们深入研究和应用。


相关文章
|
1月前
|
存储 编解码 负载均衡
数据分片算法
【10月更文挑战第25天】不同的数据分片算法适用于不同的应用场景和数据特点,在实际应用中,需要根据具体的业务需求、数据分布情况、系统性能要求等因素综合考虑,选择合适的数据分片算法,以实现数据的高效存储、查询和处理。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
1月前
|
存储 缓存 算法
分布式缓存有哪些常用的数据分片算法?
【10月更文挑战第25天】在实际应用中,需要根据具体的业务需求、数据特征以及系统的可扩展性要求等因素综合考虑,选择合适的数据分片算法,以实现分布式缓存的高效运行和数据的合理分布。
|
2月前
|
机器学习/深度学习 人工智能 算法
"拥抱AI规模化浪潮:从数据到算法,解锁未来无限可能,你准备好迎接这场技术革命了吗?"
【10月更文挑战第14天】本文探讨了AI规模化的重要性和挑战,涵盖数据、算法、算力和应用场景等方面。通过使用Python和TensorFlow的示例代码,展示了如何训练并应用一个基本的AI模型进行图像分类,强调了AI规模化在各行业的广泛应用前景。
34 5
|
2月前
|
机器学习/深度学习 人工智能 算法
【MM2024】面向 StableDiffusion 的多目标图像编辑算法 VICTORIA
阿里云人工智能平台 PAI 团队与华南理工大学合作在国际多媒体顶级会议 ACM MM2024 上发表 VICTORIA 算法,这是一种面向 StableDiffusion 的多目标图像编辑算法。VICTORIA 通过文本依存关系来修正图像编辑过程中的交叉注意力图,从而确保关系对象的一致性,支持用户通过修改描述性提示一次性编辑多个目标。
|
1月前
|
存储 JSON 算法
TDengine 检测数据最佳压缩算法工具,助你一键找出最优压缩方案
在使用 TDengine 存储时序数据时,压缩数据以节省磁盘空间是至关重要的。TDengine 支持用户根据自身数据特性灵活指定压缩算法,从而实现更高效的存储。然而,如何选择最合适的压缩算法,才能最大限度地降低存储开销?为了解决这一问题,我们特别推出了一个实用工具,帮助用户快速判断并选择最适合其数据特征的压缩算法。
51 0
|
2月前
|
人工智能 算法 前端开发
无界批发零售定义及无界AI算法,打破传统壁垒,累积数据流量
“无界批发与零售”是一种结合了批发与零售的商业模式,通过后端逻辑、数据库设计和前端用户界面实现。该模式支持用户注册、登录、商品管理、订单处理、批发与零售功能,并根据用户行为计算信用等级,确保交易安全与高效。
|
2月前
|
前端开发 算法 JavaScript
无界SaaS模式深度解析:算力算法、链接力、数据确权制度
私域电商的无界SaaS模式涉及后端开发、前端开发、数据库设计、API接口、区块链技术、支付和身份验证系统等多个技术领域。本文通过简化框架和示例代码,指导如何将核心功能转化为技术实现,涵盖用户管理、企业店铺管理、数据流量管理等关键环节。
|
2月前
|
机器学习/深度学习 算法 数据处理
EM算法对人脸数据降维(机器学习作业06)
本文介绍了使用EM算法对人脸数据进行降维的机器学习作业。首先通过加载ORL人脸数据库,然后分别应用SVD_PCA、MLE_PCA及EM_PCA三种方法实现数据降维,并输出降维后的数据形状。此作业展示了不同PCA变种在人脸数据处理中的应用效果。
38 0
|
2月前
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
94 0
下一篇
DataWorks