精华内容
下载资源
问答
  • 在本文中,我们总结了关于不变非齐次和动态平衡(DE)连续Markov随机过程一些结果。 此外,我们讨论了一些示例,并考虑了DE过程在生存分析要素中应用。 这些要素与随机二次风险率模型有关,为此我们工作1)...
  • 题目要求 根据AVL对商品进行动态平衡问题二.设计思路应用设计思路:为方便对商品库问题进行模拟,同时在运行时提示用户“输入新搜索词”及提示管理员是否需要增删库中商品,每修改一次AVL树,输出一次当前AVL...

    一.题目要求

        根据AVL对商品进行动态平衡问题

    二.设计思路

    应用设计思路:

    为方便对商品库问题进行模拟,同时在运行时提示用户“输入新的搜索词”及提示管理员是否需要增删库中商品,每修改一次AVL树,输出一次当前的AVL树,形式为:商品名称 树中的高度 左节点名称 右节点名称(如缺少左/右节点,用None代替),初始设置为:

     

    库中默认商品包含在number_list中,建立的AVL树为treeoldwords中包含已入库商品名及其对应搜索频次,newwords包含未入库但被检索的商品名。Searchnum为用户搜索次数。用户搜索达到一定次数时需删除低频次商品,将触发机制设置为delnum,每搜索delnum次商品,检查是否要删除某些商品,并提示管理员。N=2表示每delnum次搜索,若每个商品搜索次数未达到N,提示管理员。W=3表示若新商品累计搜索次数(按照论文的思想,未限定时间,只累计新商品总的搜索次数)达到3次时,提示管理员是否需要添加该商品。

    删除操作设计思路:

       将删除的情况分类讨论:

    l 删除的点不存在

    l 删除叶节点

    l 删除节点只有左孩子

    l 删除节点只有右孩子

    l 删除节点左右孩子都有,此时需要找到左子树最右节点,往上提

     

     

     

     

     

    三.程序主体

    # coding=utf-8
    class AVLTreeNode():#AVL树节点包含的信息:关键值key,父节点p,左节点left,右节点right,高度height
        
    def __init__(self, key):
            self.key = key
            self.p = None
            
    self.left = None
            
    self.right = None
            
    self.height = 0

    def get_height(node):#获得节点高度,若节点为空返回高度-1
        
    return node.height if node else -1


    def get_maximum(node):#找到当前点向下最右节点,即该子树最大值
        
    temp_node = node
        while temp_node.right:
            temp_node = temp_node.right
        return temp_node


    def get_minimum(node):#找到当前点向下最左节点,即该子树最小值
        
    temp_node = node
        while temp_node.left:
            temp_node = temp_node.left
        return temp_node


    def preorder_tree_walk(node):#迭代输出关键值和高度,顺序为当前点,左点,右点
        
    if node:
            if node.left and node.right:
                print(node.key, node.height,node.left.key,node.right.key)
            elif node.left :
                print(node.key, node.height, node.left.key,'None')
            elif node.right:
                print(node.key, node.height, 'None',node.right.key)
            else:
                print(node.key, node.height, 'None','None')
            preorder_tree_walk(node.left)
            preorder_tree_walk(node.right)


    def left_left_rotate(tree, node):#即LL,左高插入左边
        # 先将 node 和 node_left 之间及其左右节点赋值 (node_left.left node.right 保持不变)
        
    node_left = node.left
        node.left = node_left.right
        node_left.right = node
        if not node.p:
            tree.root = node_left
            node_left.p = None
        elif
    node == node.p.left:
            node.p.left = node_left
            node_left.p = node.p
        elif node == node.p.right:
            node.p.right = node_left
            node_left.p = node.p
        node.p = node_left
        while node:
            node.height = max(get_height(node.left), get_height(node.right)) + 1
            node = node.p


    def right_right_rotate(tree, node):#即RR,右高插入右边
        
    node_right = node.right
        node.right = node_right.left
        node_right.left = node
        if not node.p:
            tree.root = node_right
            node_right.p = None
        elif
    node == node.p.left:
            node.p.left = node_right
            node_right.p = node.p
        elif node == node.p.right:
            node.p.right = node_right
            node_right.p = node.p
        node.p = node_right
        while node:
            node.height = max(get_height(node.left), get_height(node.right)) + 1
            node = node.p


    def left_right_rotate(tree, node):#即LR,左高插入右边
        
    right_right_rotate(tree, node.left)
        left_left_rotate(tree, node)


    def right_left_rotate(tree, node):#即Rl,右高插入左边
        
    left_left_rotate(tree, node.right)
        right_right_rotate(tree, node)


    class AVLTree(object):
        def __init__(self):
            self.root = None

        def
    search(self, key):
            if not self.root:#空树
                
    return None
            else
    :
                return self._search(key)

        def _search(self, key):#从根节点向下查找,返回key ==start.key的Start节点
            
    start = self.root
            while start:
                if key < start.key:
                    start = start.left
                elif key > start.key:
                    start = start.right
                else:
                    return start
            return None

        
    ############################################################插入
        
    def insert(self, node):
            temp_root = self.root
            temp_node = None#初始化插入点父根
            # 找到要插入的父节点(temp_node)
            
    while temp_root:#temp_root相当于一个中间寄存器
                
    temp_node = temp_root
                if node.key < temp_node.key:
                    temp_root = temp_root.left
                elif node.key > temp_node.key:
                    temp_root = temp_root.right
                else:
                    raise KeyError("Error!")##要插入的点已在树中,则报错

            # 如果父节点为空 则说明这是一个空树 把 root 赋值即可
            
    if not temp_node:
                self.root = node
            elif node.key < temp_node.key:#父节点非空,且应该在temp_node左节点处插入
                
    temp_node.left = node
                node.p = temp_node#.p代表父节点
                
    temp_node.height = max(get_height(temp_node.left), get_height(temp_node.right)) + 1#更新被插入的父节点的高度
                
    temp_p = temp_node.p#几个点的顺序:temp_p——temp_node——node(新插入的点)
                
    while temp_p:#不断向上更新高度
                    
    temp_p.height = max(get_height(temp_p.left), get_height(temp_p.right)) + 1
                    temp_p = temp_p.p
            elif node.key > temp_node.key:#与上面的if过程对称,是在temp_node右节点处插入
                
    temp_node.right = node
                node.p = temp_node
                temp_node.height = max(get_height(temp_node.left), get_height(temp_node.right)) + 1
                temp_p = temp_node.p
                while temp_p:
                    temp_p.height = max(get_height(temp_p.left), get_height(temp_p.right)) + 1
                    temp_p = temp_p.p
            self.fixup(node)

        def fixup(self, node):#对新插入/删除的点进行fixup调整树
            
    if node == self.root:#从空树插入一个点后不需要调整
                
    return
            while
    node:#从插入点往上找失衡位置,
                
    if get_height(node.left) - get_height(node.right) == 2:#左高插入左边后,左子树高度高了2
                    
    if node.left.left:
                        left_left_rotate(self, node)#LL调整
                    
    else:
                        left_right_rotate(self, node)
                    break       #使用break后调整完即结束了
                
    elif get_height(node.right) - get_height(node.left) == 2:#右子树高度高了2
                    
    if node.right.right:
                        right_right_rotate(self, node)
                    else:
                        right_left_rotate(self, node)
                    break
                
    node = node.p
    ############################################################删除
        
    def delete(self, key):
            temp_node = self.root
            while temp_node:  #从根节点向下定位需要删除的位置
                
    if key > temp_node.key:
                    temp_node = temp_node.right
                elif key < temp_node.key:
                    temp_node = temp_node.left
                else:
                    break  #找到需要删除的位置(key == temp_node.key)即停止
            
    if not temp_node:#没有需要删除的点
                
    return False
            
    ##################################
            
    elif temp_node.left and temp_node.right is None:  # 只有左子树
                
    if temp_node == temp_node.p.left:  # 要删除的点是其父节点的左孩子
                    
    temp_node.p.left =temp_node.left
                    temp_node.left.p=temp_node.p
                else:
                    temp_node.p.right =temp_node.left
                    temp_node.left.p = temp_node.p
                temp_node =temp_node.left
            elif temp_node.left is None and temp_node.right :  # 只有右子树
                
    if temp_node == temp_node.p.left:  # 要删除的点是其父节点的左孩子
                    
    temp_node.p.left =temp_node.right
                    temp_node.right.p=temp_node.p
                else:
                    temp_node.p.right =temp_node.right
                    temp_node.right.p=temp_node.p
                temp_node =temp_node.right
            elif temp_node.left is None and temp_node.right is None:  # 删除的是叶节点
                
    if temp_node == temp_node.p.left:  # 要删除的点是其父节点的左孩子
                    
    temp_node.p.left =None
                else
    :  # 替换要删除的点
                    
    temp_node.p.right =None
                
    temp_node =temp_node.p
            #####################################



            
    elif temp_node.left and temp_node.right:  # 要删除的点左右孩子都有
                # 找到左子树中的最大值往上提
                
    node_max = get_maximum(temp_node.left)  # 删除节点左子树最右节点
                # 第一步:#处理左子树中的最大值以下的节点
                
    if node_max.left:  # 如果左树高提左树最大值,且该最大值有左子树(根据定义,最大子节点一定没有右孩子)。提最大值时需要修改下其余的连接关系
                    
    if node_max == node_max.p.left:  # 要最大点是其父节点的左孩子
                        
    node_max.left.p = node_max.p
                        node_max.p.left = node_max.left
                    else:
                        node_max.p.right = node_max.left
                        node_max.left.p = node_max.p
                else:
                    if node_max == node_max.p.left:  # 要最大点是其父节点的左孩子
                        
    node_max.p.left = None
                    else
    :
                        node_max.p.right = None
                
    # 第二步:用node_min替换temp_node,处理向下的连接
                
    node_max.right = temp_node.right
                temp_node.right.p = node_max
                if temp_node.left != node_max:
                    node_max.left = temp_node.left
                    if temp_node.left != None:
                        temp_node.left.p = node_max
                else:
                    node_max.left = None
                
    # 第三步:处理node_min向上的连接
                
    temp_node_new = node_max.p  # 当前节点
                
    if temp_node.p:  # 需要删除的点有父节点
                    
    if temp_node == temp_node.p.left:  # 要删除的点是其父节点的左孩子
                        
    temp_node.p.left = node_max  # 用左最大替换要删除的位置
                        
    node_max.p = temp_node.p
                    else:  # 替换要删除的点
                        
    temp_node.p.right = node_max
                        node_max.p = temp_node.p
                else:  # 要删除的点是根节点
                    
    self.root = node_max
                    node_max.p = None
                
    temp_node = temp_node_new  # 当前节点
            
    temp_p = temp_node
            while temp_p:
                temp_p.height = max(get_height(temp_p.left), get_height(temp_p.right)) + 1
                temp_p = temp_p.p
            self.fixup(temp_node)

     

    四.主函数

    #################################################################
    def main():
        number_list = ('HE','NJ','FS','YJ','XZ')
        tree = AVLTree()
        oldwords={}
        newwordes={}
        searchnum=0#用以累计到delnum
        
    delnum=10#为调试方便,设定每输入10次会删去树中搜索次数小于阈值N的商品
        
    N=2#被删除的阈值
        
    W=3#自定义新词添加的阈值,每有3词新词被检索,则提示是否增加到树中
        
    for number in number_list:
            node = AVLTreeNode(number)
            tree.insert(node)
            oldwords[number]=1
        print('按照论文数据给出的AVL树')
        preorder_tree_walk(tree.root)
        #######################################根据搜索做出增删AVL树
        
    while True:
            a = input("输入搜索词:")
            searchnum+=1
            if a in oldwords:#树中已含节点有被删除的风险
                
    oldwords[a]+=1
                ###################################################################################

            
    else:#新搜索词累计到一定次数W则有机会添加到AVL树中
                
    if a not in newwordes:
                    newwordes[a]=1
                else:
                    newwordes[a]+=1
                    if newwordes[a]>=W:#有希望被添加到树中,提醒管理员
                        
    print('最新热搜商品:',a)
                        b = input('是否添加到库中(请输入yes/no):')
                        if b=='yes':
                            newproduct=AVLTreeNode(a)
                            tree.insert(newproduct)
                            oldwords[a]=W
                            newwordes.pop(a)
                            preorder_tree_walk(tree.root)
                        else:#管理员选择暂不添加
                            
    newwordes.pop(a)

            deloldwords=[]
            if searchnum==delnum:#搜索次数达到设定值,提示是否删去某些词
                
    searchnum=0
                for word in oldwords:
                    frequency=oldwords[word]
                    oldwords[word] = 0
                    if frequency<N:
                        print('低搜索商品:',word)
                        z = input('是否从库中删除(请输入yes/no):')
                        if z=='yes':
                            tree.delete(word)
                            deloldwords.append(word)
                            preorder_tree_walk(tree.root)
                for p in deloldwords:
                    oldwords.pop(p)
                print('目前库中商品:',oldwords)


    if __name__ == '__main__':
        main()

     

    五.运行结果

    C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe C:/Users/Administrator/PycharmProjects/untitled1/AVL.py

    按照论文数据给出的AVL

    HE 2 FS XZ

    FS 0 None None

    XZ 1 NJ YJ

    NJ 0 None None

    YJ 0 None None

    输入搜索词:HE

    输入搜索词:FS

    输入搜索词:AA

    输入搜索词:XZ

    输入搜索词:YJ

    输入搜索词:AA

    输入搜索词:YJ

    输入搜索词:AA

    最新热搜商品: AA

    是否添加到库中(请输入yes/no):yes

    HE 2 FS XZ

    FS 1 AA None

    AA 0 None None

    XZ 1 NJ YJ

    NJ 0 None None

    YJ 0 None None

    输入搜索词:XZ

    输入搜索词:YJ

    低搜索商品: NJ

    是否从库中删除(请输入yes/no):yes

    HE 2 FS XZ

    FS 1 AA None

    AA 0 None None

    XZ 1 None YJ

    YJ 0 None None

    目前库中商品: {'HE': 0, 'FS': 0, 'YJ': 0, 'XZ': 0, 'AA': 0}

    输入搜索词:

    六.结果分析

    初始商品有:'HE','NJ','FS','YJ','XZ'

    初始AVL树为:

     

    后不断输入新的搜索词,新搜索词AA累计搜索次数达到W=3次时,提示管理员是否需要新加,键入yes后新的搜索树中包含AA

     

      累计搜索次数达到delnum=10次时,检查搜索次数不到N=2的商品(初始化AVL树时,默认搜索次数已有1,不占后面10次搜索的名额),管理员同意删除后该商品从库中删除:

     

    展开全文
  • 报道了一种基于解调技术使用双光纤光栅...在外界拉力下一个光纤布拉格光栅反射波长漂移被转变成从另一个被压电陶瓷片调制光栅反射光脉冲间隔变化。实验表明,当测量一个40 N以内力时,测量精度可达到2.5 mN。
  • 风机调压等技术特点和优势,形成了气体流场动态平衡多点调控技术,于回采工作面、上覆采空区、灾变区域之间实现气体流场"动态平衡",达到抑制有害气体侵入、减少采空区供氧目的,通过在现场实际应用,取得了良好...
  • 以TA动态平衡阀为例,阐述系统流量平衡在保证室内环境舒适度前提下,减少能量损耗重要性,所以平衡阀设计在工程设计中发挥着重要作用。为了使平衡阀选择达到功能性和经济性最优配比,详细阐述了在工程设计中...
  • 动态经典应用

    2019-04-27 17:36:25
    基于动态基本操作,我们很容易在较短时间内求得任意两个结点u和结点v(在同一棵树中)最近公共祖先。首先对u执行access(u)操作,同时记录被访问过结点(在平衡树上打标机即可);然后执行access(v)...

    ——————摘自《高级数据结构》

    1。求最近公共祖先
    基于动态树的基本操作,我们很容易在较短的时间内求得任意两个结点u和结点v(在同一棵树中)的最近公共祖先。首先对u执行access(u)操作,同时记录被访问过的结点(在平衡树上打标机即可);然后执行access(v)操作,当第一次碰到已经访问过的点w时,该w就是u和v的最近公共祖先。时间复杂度是O(nlog2n).
    2.并查集操作
    在并查集操作一章我们看到了如何维护两个集合进行合并操作,然而并查集不支持既有合并又有分离的操作。类似并查集的树形结构,用动态树来维护这种森林连通性的变换非常方便
    3.求最大流
    通过用动态树改造最短路径增光路算法,可以再O(nmlog2n)的时间复杂度内得到网络最大流,其中n为顶点数,m为边数。算法的大致思想:刚开始执行时,每个顶点为单独的一棵树,每次增广的时候选择一条未满流的边,用来给当前的树连接新的结点,如果发现已经找到了汇点,那么每次增广的流量就是树中源点到汇点路径上所有边中最小增广量,将路径上的边增广相应流量后,将满流边删去,然后继续执行增广。
    4。求最小生成树
    增量构造法求最小生成树的方式————依次添加边,如果发现当前的边添加后形成了环,那么将环上的最大边权删去,直到更新完了为止。这种增量式的算法如果用动态树维护将会非常高效。我们所需要的操作除了几个动态树级别的操作之外,还需要维护任意两个点之间的路径上的权值最大的边,该信息可以用平衡树维护。
    除了一般的最小生成树之外,其他的一些问题,例如度限制最小生成树或者对边使用有限制的生成树也用动态树问题来建模也可以得到不错的效果。

    展开全文
  • 以拟稳态扩散和体积物质平衡方程为基础,建立气体扩散量与含水饱和度关系,结合拟稳态产能方程,得到考虑煤层气体拟稳态扩散的动态预测模型。模型对煤层气井生产中后期具有较好拟合度,通过计算,认为扩散作用在整个...
  • 在摄像机发展岁月里,从初真空管摄像机发展到现在CCD、CMOS、DPS摄像机,随着摄像机应用的不断发展,出现了各种专用摄像技术,宽动态技术便是其中之一。对于一些明暗反差强烈特殊环境,普通摄像机针对图像...
  • 针对谐波平衡分析中传统算法存在初值限制,以及智能算法收敛速度慢缺点,提出一种基于BFGS(Broyden-Fleteher-Goldfarl-Shanno)算法局部搜索策略自适应蜂群算法。该算法在基本蜂群算法基础上引入非线性的动态调整...
  • 论文研究-国民经济动态平衡与投资优化模型.pdf, “部门联系平衡法”,是美国著名经济学家W.Leontief所创立“投入产出法”在研究国民经济综合平衡问题时具体应用。作为一种利用现代数学和电子计算技术等科学技术,...
  • 本文提出了一种基于平衡的动态比较器失调电压分析设计技术。以两支路电压电流相等的平衡态为分析基础,通过在复位电压跳变时刻引入补偿电压方法,逐一分析了动态比较器各晶体管参数对总体失调电压影响,建立了...
  • 在摄像机发展岁月里,从最初真空管摄像机发展到现在CCD、CMOS、DPS摄像机,随着摄像机应用的不断发展,出现了各种专用摄像技术,宽动态技术便是其中之一。对于一些明暗反差强烈特殊环境,普通摄像机针对...
  • 高庄煤矿选煤厂通过建立煤泥水水平衡系统,将生产的"水"环节自动连接起来,实现了煤泥水处理工艺、煤泥水沉降特性与生产过程洗水平衡的完美结合,探索并实现了煤泥水系统的自动化闭环控制,达到了动态水平衡控制的目的。
  • 针对上述变化给企业混流装配线带来的影响进行了研究,以最小化生产节拍、工作站间的负荷和工人完成新装配任务的调整成本为优化目标来建立混装线再平衡的数学模型;设计了一种新的多目标粒子群算法求解模型,算法中...
  • 建立其动态投入产出模型, 用以解决煤炭企业维持简单再生产和扩大再生产过程中各生产部门生产能力合理规划、资源合理配置、投资与产出增长的动态平衡等问题, 进而优化企业投资结构和产品结构, 寻求矿区最佳发展...
  • 基于连续采煤机平行作业开采工艺理论研究和现场应用,提出了以提高连续采煤机作业效率为中心,以优化劳动组织工艺为表征的平衡开采理论,并采用统筹原理分析了巷道掘进速度和支护速度差异、各类巷道长度差异、调机距离...
  • 目的:分析动态步态指数(DGI)-巴西简要建议的应用结果,并与原始版本建立关联。 方法:这项研究得到塞尔希培联邦大学伦理与研究委员会的批准(编号0197.0.107000.09)。 自2014年以来,我们分析了223名社会活跃...
  • 为控制由电容补偿造成...与常规SVPWM系统相比,应用新型非线性动态控制系统后,单位时间内电容补偿量不超过7.5×1013 T,高、低电容数值间物理落差低至2.0×1013 T,由电容补偿造成电网损耗行为得到有效控制。
  • 在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。...
    白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题。白平衡是随着电子影像再现色彩真实而产生的,在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。它是实现摄像机图像能精确反映被摄物的色彩状况,有手动白平衡和自动白平衡等方式,本文简要的介绍了几种自动白平衡算法。

    一、原始的灰度世界算法

      灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。

            (1)直接给定为固定值, 取其各通道最大值的一半,即取为127或128;

           (2)令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。

             算法的第二步是分别计算各通道的增益:

               Kr=K/Raver;

        Kg=K/Gaver;

               Kb=K/Baver;

           算法第三步为根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:

                 Rnew = R * Kr;

        Gnew = G * Kg;

         Bnew = B * Kb;

             对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。

             a、 直接将像素设置为255,这可能会造成图像整体偏白。

             b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。

    二、完美反射算法

          当初写这个代码的时候的一些参考文献一下子也找不到了,就从已经写好的代码中描述下该算法的过程吧。

          原理:完美全反射理论perfect Reflector假设图像上最亮点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值,具体编码步骤如下:

          (1)计算每个像素的R\G\B之和,并保存到一临时内存块中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Sum = (short)(*(Pointer) + *(Pointer + 1) + *(Pointer + 2));     // R+G+B
            HistRGB[Sum]++;
            *SumP = (short)Sum;
            Pointer += 3;
            SumP++;
        }
    }

         (2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (Y = 767; Y >= 0; Y--)
    {
        Sum += HistRGB[Y];
        if (Sum > Width * Height * Ratio / 100)
        {
            Threshold = Y;
            break;
        }
    }

        (3)遍历图像中的每个点,计算其中R+G+B值大于T的所有点的R\G\B分量的累积和的平均值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            if (*SumP > Threshold)
            {
                AvgB += *Pointer;
                AvgG += *(Pointer + 1);
                AvgR += *(Pointer + 2);             // 为获得增益做准备
                Amount++;
            }
            Pointer += 3;
            SumP++;
        }
    }
    AvgB /= Amount;
    AvgG /= Amount;
    AvgR /= Amount;

       (4)对每个点将像素量化到[0,255]之间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Blue = *Pointer * MaxValue / AvgB;                                   // 另外一种算法需要先计算不抑制重新计算的RGB的范围,然后求RGB的最大值,如果最大值大于255,则所有的结果都要除以最大值在乘以255,但实际表明该算法、   不合适;
            Green = *(Pointer + 1) * MaxValue / AvgG;
            Red = *(Pointer + 2) * MaxValue / AvgR;
            if (Red > 255) Red = 255; else if (Red < 0) Red = 0;                // 这里需要判断,因为RGB空间所有的颜色转换到YCbCr后,并不是填充满了0-255的范围的,反转过去就会存在一些溢出的点。
            if (Green > 255) Green = 255; else if (Green < 0) Green = 0;        // 编译后应该比三目运算符的效率高
            if (Blue > 255) Blue = 255; else if (Blue < 0) Blue = 0;
            *Pointer = (byte)Blue;
            *(Pointer + 1) = (byte)Green;
            *(Pointer + 2) = (byte)Red;
            Pointer += 3;
        }

    }


    三、动态阈值算法

          参考论文:A Novel Automatic White Balance Method For Digital Still Cameras

          同经典的一些算法相同,算法分为两个步骤:白点检测和白点调整。

          白点检测:

               (1)为了增强算法的鲁棒性,原文将图像分成12部分,其中宽高比为4:3,关于这一点,我认为不合理,对图像不是通用的,后文再说。

                (2)计算每个区域的Cb\Cr分量的平均值Mb/Mr

                (3)按下式计算每个区域的Cb\Cr分量的绝对差的累积值Db/Dr

                                     

                                     

                      上式中N为每个区域的像素数。

             (4)如果Db/Dr的值偏小,则我们忽略这一块,因为这表明这一块的颜色分布比较均匀,而这样的局部对于白平衡不好。这个偏小的准则我们稍微再谈。

             (5)统计对于除了符合第四条的的其他区域的Mb/Mr/Db/Dr的平均值作为整幅图像的Mb/Mr/Db/Dr值。

            关于这一条,原文的话是:The final Mb、Mr、Db、Dr are obtained by taking the average of those regions that pass this additional step。

           我在实际中做的时候就是分别对每块进行的,似乎效果也还不错。

             (6)按下述规则初步确定哪些点是属于白色参考点:

                           

                            

             (7)对于初步判断已经属于白色参考点的像素,按大小取其亮度值为前10%的位最终确定的白色参考点。

          白点调整:

         (1)计算白色参考点亮度值的平均值Raver,Gaver,Baver,(各通道分开计算)。

              (2)按照以下各式计算每个通道的增益:

                 

                           

                          

                  式中,Ymax就是YCbCr颜色空间中Y分量的在整幅图像中的最大值。

              (3)按照以下各式计算最终每个通道的颜色值:

                          

                          

                          

              其中R/G/B为在原始的颜色空间中的值,注意这里要进行溢出检测的。

            简单的谈下白点检测的分块操作吧,原文把图像分成4*3的12快,这样做事针对于我们很多数码照片是这个比例的,如果通用,我觉得应该用每个块的大小来控制,比如每块为 100*100个像素。

        该算法效果非常好;对块大小不太敏感,因此非常适合于自动化操作。


    同样,提供个编译好的文件给有兴趣研究该算法的朋友看看效果:

          http://files.cnblogs.com/Imageshop/AutoWhiteBalance.zip

    ********作者: laviewpbt   时间: 2013.4.20    联系QQ:  33184777  转载请保留本行信息*********



    展开全文
  • 平衡滚子链谐波传动是一种以滚子链取代柔轮、静动态平衡、减速与输出复合同步新型谐波传动。着重面向一般工业领域常用传动需求,给出几种具有产品创新开发价值结构方案及相关应用,其中包括全平衡滚子链谐波...
  • 这种应用的系统分析方法涉及对复杂运动行为测量,以便阐明多个传感器数据融合,以便可靠,有效地获取人类空间行为动力学,运动学和肌电数据。 所获取运动学信号和相关动力学信号表示叠加身体部分之间...
  • 针对智能交通路径诱导目前存在实时性差和求解效率低问题,提出了将神经网络与遗传算法结合的动态路径诱导方法,研究了基于神经网络交通信息实时预测方法,构造了具有时变性路阻矩阵,解决了传统静态路阻存在...
  • 指南如何阅读本文件 请专心阅读本文档,并清楚地了解应用程序的工作方式。... 这是总共5个单独的应用程序(1个前端+ 4个后端)。 microservice-ui(前端) 服务注册 api网关 产品服务 提供服务 什么是微
  • 在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。...
    http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html
    白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题。白平衡是随着电子影像再现色彩真实而产生的,在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。它是实现摄像机图像能精确反映被摄物的色彩状况,有手动白平衡和自动白平衡等方式,本文简要的介绍了几种自动白平衡算法。

    一、原始的灰度世界算法

      灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。

            (1)直接给定为固定值, 取其各通道最大值的一半,即取为127或128;

           (2)令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。

             算法的第二步是分别计算各通道的增益:

                 Kr=K/Raver;

           Kg=K/Gaver;

                 Kb=K/Baver;

             算法第三步为根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:

                 Rnew = R * Kr;

           Gnew = G * Kg;

           Bnew = B * Kb;

             对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。

             a、 直接将像素设置为255,这可能会造成图像整体偏白。

             b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。

            一般来说,灰度世界算法的效果还是比较好的呢,并且该算法的执行速度非常之快,目前也存在了不少对该算法进行改进的效果,有时间我在整理一下。

             

             

                                         原图                                                                            处理后的图

    二、完美反射算法

          当初写这个代码的时候的一些参考文献一下子也找不到了,就从已经写好的代码中描述下该算法的过程吧。

          原理:完美全反射理论perfect Reflector假设图像上最亮点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值,具体编码步骤如下:

          (1)计算每个像素的R\G\B之和,并保存到一临时内存块中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Sum = (short)(*(Pointer) + *(Pointer + 1) + *(Pointer + 2));     // R+G+B
            HistRGB[Sum]++;
            *SumP = (short)Sum;
            Pointer += 3;
            SumP++;
        }
    }

         (2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (Y = 767; Y >= 0; Y--)
    {
        Sum += HistRGB[Y];
        if (Sum > Width * Height * Ratio / 100)
        {
            Threshold = Y;
            break;
        }
    }

        (3)遍历图像中的每个点,计算其中R+G+B值大于T的所有点的R\G\B分量的累积和的平均值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            if (*SumP > Threshold)
            {
                AvgB += *Pointer;
                AvgG += *(Pointer + 1);
                AvgR += *(Pointer + 2);             // 为获得增益做准备
                Amount++;
            }
            Pointer += 3;
            SumP++;
        }
    }
    AvgB /= Amount;
    AvgG /= Amount;
    AvgR /= Amount;

       (4)对每个点将像素量化到[0,255]之间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = bmp.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Blue = *Pointer * MaxValue / AvgB;                                   // 另外一种算法需要先计算不抑制重新计算的RGB的范围,然后求RGB的最大值,如果最大值大于255,则所有的结果都要除以最大值在乘以255,但实际表明该算法、   不合适;
            Green = *(Pointer + 1) * MaxValue / AvgG;
            Red = *(Pointer + 2) * MaxValue / AvgR;
            if (Red > 255) Red = 255; else if (Red < 0) Red = 0;                // 这里需要判断,因为RGB空间所有的颜色转换到YCbCr后,并不是填充满了0-255的范围的,反转过去就会存在一些溢出的点。
            if (Green > 255) Green = 255; else if (Green < 0) Green = 0;        // 编译后应该比三目运算符的效率高
            if (Blue > 255) Blue = 255; else if (Blue < 0) Blue = 0;
            *Pointer = (byte)Blue;
            *(Pointer + 1) = (byte)Green;
            *(Pointer + 2) = (byte)Red;
            Pointer += 3;
        }
    }

            

                

                

                                    原图                                                  Ratio=10%                                            Ratio=2%

        从效果上看,该算法应该比灰度世界的效果要好些,但是也还是受到Ratio这个参数的影像。特别是第二个图片,过高的Ration导致图片过于泛白。这个问题可以还是最后量化的哪一步引起的,我会抽空再研究一下其他的量化方式,尽量降低Ration的影响。

        针对上述的第二步,看到很多matlab和VC的代码,有很多人居然先用快速排序对累加后的数据进行排序,然后再取其10%的最大值,对图像的数据进行排序,可能就是再快速的排序都快不起来吧,看到这,也许全国人民都笑了。

    三、动态阈值算法

          参考论文:A Novel Automatic White Balance Method For Digital Still Cameras

          同经典的一些算法相同,算法分为两个步骤:白点检测和白点调整。

          白点检测:

               (1)为了增强算法的鲁棒性,原文将图像分成12部分,其中宽高比为4:3,关于这一点,我认为不合理,对图像不是通用的,后文再说。

                (2)计算每个区域的Cb\Cr分量的平均值Mb/Mr

                (3)按下式计算每个区域的Cb\Cr分量的绝对差的累积值Db/Dr

                                     

                                     

                      上式中N为每个区域的像素数。

             (4)如果Db/Dr的值偏小,则我们忽略这一块,因为这表明这一块的颜色分布比较均匀,而这样的局部对于白平衡不好。这个偏小的准则我们稍微再谈。

             (5)统计对于除了符合第四条的的其他区域的Mb/Mr/Db/Dr的平均值作为整幅图像的Mb/Mr/Db/Dr值。

            关于这一条,原文的话是:The final Mb、Mr、Db、Dr are obtained by taking the average of those regions that pass this additional step。

           我在实际中做的时候就是分别对每块进行的,似乎效果也还不错。

             (6)按下述规则初步确定哪些点是属于白色参考点:

                           

                            

             (7)对于初步判断已经属于白色参考点的像素,按大小取其亮度值为前10%的位最终确定的白色参考点。

          白点调整:

         (1)计算白色参考点亮度值的平均值Raver,Gaver,Baver,(各通道分开计算)。

              (2)按照以下各式计算每个通道的增益:

                 

                           

                          

                  式中,Ymax就是YCbCr颜色空间中Y分量的在整幅图像中的最大值。

              (3)按照以下各式计算最终每个通道的颜色值:

                          

                          

                          

              其中R/G/B为在原始的颜色空间中的值,注意这里要进行溢出检测的。

            简单的谈下白点检测的分块操作吧,原文把图像分成4*3的12快,这样做事针对于我们很多数码照片是这个比例的,如果通用,我觉得应该用每个块的大小来控制,比如每块为 100*100个像素。

              这个算法的效果如下:

              

              

              

                               原图                                              块大小50*50                    块大小100*100

          上三图表明:1、该算法效果非常好;2、对块大小不太敏感,因此非常适合于自动化操作。

           关于RGB到YCbCr的快速转换,可以参考:颜色空间系列3: RGB和YCbCr颜色空间的转换及优化算法 

          由于在上述链接的文章中,YCbCr颜色空间已经被转换到[0,255],因此白色检测部分的第(6)条中的sign函数就不需要了。

          同样,提供个编译好的文件给有兴趣研究该算法的朋友看看效果:

          http://files.cnblogs.com/Imageshop/AutoWhiteBalance.zip

       后记:

         针对动态阈值法,很多朋友反映如果YCbCr的值量化在0到255之间的话会出现所有的像素都会被式(6)初步判断为白色参考点。这样前期的工作就失去了意义,算法就变成了类似于完美反射算法那了,稍微有点不同的地方就是两者选择两点的准则有所不同。虽然这样做的最终结果还算不错,但确实和论文的本意像违背了,后面经过实践,如果把YCbCr的值量化在-127到128之间,式6中的Sgn同样适用,则初步判断为白点的数会大量的减少,对于同一个图片,同一个参数两个算法的最终的效果比较如下:

       更新后的下载链接依旧如下,以增加了修正后的功能。

              

              

     

      ***************************作者: laviewpbt   时间: 2013.4.20    联系QQ:  33184777  转载请保留本行信息*************************

    展开全文
  • 利用设备上自带的动态传感器,通过摇晃手机等方式,移动游戏物体来游玩游戏。 为了成功理解陀螺仪使用,我试着还原了一个类似小游戏。 可以在这里获取我游戏demo. 首先是…球? 为了尽可能简单地去体现陀螺仪...
  • 利用设备上自带的动态传感器,通过摇晃手机等方式,移动游戏物体来游玩游戏。 为了成功理解陀螺仪使用,我试着还原了一个类似小游戏。 可以在这里获取我游戏demo. 首先是…球? 为了尽可能简单地去体现陀螺仪...
  • 平衡是随着电子影像再现色彩真实而产生,在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术发展使得白平衡调整变得越来越简单容易,但许多使用者...
  • 选煤厂生产过程中受到生产矿井井下大电流短路故障...现场应用结果分析表明,这种电压恢复器(DVR)能够在平衡电压和不平衡电压跌落情况下均能可靠地补偿井下大电流短路造成电压跌落,有效地保证了选煤厂正常有序生产。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 716
精华内容 286
关键字:

动态平衡的应用