[Color]深切学习YUV色彩模型必发365bifa0000 V1.1

by admin on 2019年2月28日

 

  能够看来,U、V、RAV4、B 的一个钱打二17个结正是用乘法缩放数值,完全能够数组查表。
  至于Y的计算,请参考《彩色转灰度算法彻底学习》
  唯一麻烦一点的是G,因为它有七个乘法,直接整数查表可能不可靠赖。所以能够设想将数值缩放65536倍(十四个人精度)。
  大致是这般:
Y = (R*19595 + G*38469 + B*7472) >> 16
U = YUV_B2U[0x100 + B – Y]
V = YUV_R2V[0x100 + R – Y]

日常在同盟社不忙的时候,就喜好写一些小功效怎样的,一来复习复习,二来能够窥见部分题目。

File:      StudyYUV.txt
Name:      深切学习YUV色彩模型
Author:    zyl910
Version:   V1.1
Updata:    2006-5-28

 

  近期忽然又对图形学有了兴趣,翻出了多年前读书图形学的笔记,感触良多。于是将它们整理好发了上去。

意义图,没有录像gif的

  完整的转移公式:
[Y] = [   0.299          0.587           0.114       ]   [R]
[U] = [( -0.299)/2.032 (-0.587)/2.032 (1-0.114)/2.032] * [G]
[V] = [(1-0.299)/1.140 (-0.587)/1.140 ( -0.114)/1.140]   [B]

 

 

直白上代码:

  正好与YUV转SportageGB的周到符合。
  完整的变换公式:
B = Y + 2.032*U
R = Y + 1.140*V
G = Y – (0.114*2.032 / 0.587)*U – (0.299*1.140 / 0.587)*V

 

2.1 YUV转RGB

必发365bifa0000 1

2.3 小结

js

贰 、那个变换全面是什么样演绎出来的?

 

 

本来准备打包一下的,要下班时来职分了,飞了….

  所以大家得以将U、V部分的转换矩阵看成那些样子:
U: (1 / 2.032) * [ -0.299 -0.587 1-0.114]
V: (1 / 1.140) * [1-0.299 -0.587  -0.114]

var clock=(function(){
    function _canvasClock(){
        var cvs=document.getElementById('canvas');
        var ctx=cvs.getContext('2d');
        var PI=Math.PI;
        var lineWidth=5;                                             //线宽
        var gradient=ctx.createLinearGradient(10,10,580,580);        //设置圆的颜色渐变
        gradient.addColorStop("0","#a251ff");
        gradient.addColorStop(1,"#2ec2ff");
        ctx.fillStyle = '#ef6670';
        ctx.fillRect(0,0,600,600);
        var drawBig=function(){
            var time=new Date();
            var second=time.getSeconds();                            //秒
            var Minute=time.getMinutes();                            //分
            var hour=time.getHours();                                //时
            //hour=hour+Minute/60;
            hour=hour>12?hour-12:hour;                               //表盘只有12小时

            ctx.clearRect(0,0,600,600);                              //清空给定矩形内的指定像素
            //画圆
            ctx.beginPath();
            ctx.lineWidth=lineWidth;
            ctx.strokeStyle=gradient;
            ctx.arc(300,300,290,0, PI * 2,false);
            ctx.stroke();
            ctx.closePath();

            ctx.beginPath();
            ctx.lineWidth=lineWidth;
            ctx.strokeStyle=gradient;
            ctx.arc(300,300,10,0, PI * 2,false);
            ctx.stroke();
            ctx.closePath();

            for(var i=0;i<60;i++){  
                ctx.save();                         //保存之前画布状态   
                ctx.lineWidth=4;                   //设置分针的粗细                 
                ctx.strokeStyle="#616161";          //设置分针的颜色                 
                ctx.translate(300,300);             //画布圆点设置        
                ctx.rotate(i*PI/30);                //角度*Math.PI/180=弧度,设置旋转角度 
                ctx.beginPath();                    //开始一条路径
                ctx.moveTo(0,-287);                 //相对画布圆点路径的起点
                ctx.lineTo(0,-283);                 //相对画布圆点路径的终点
                ctx.closePath();                    //结束一条路径
                ctx.stroke();                       //实际地绘制出通过 moveTo()和 lineTo()方法定义的路径
                ctx.restore();                      //restore() 方法将绘图状态置为保存值
            }

            for(var i=0;i<12;i++){
                ctx.save();
                ctx.lineWidth=4;
                ctx.strokeStyle=gradient;    
                ctx.translate(300,300);   
                ctx.rotate(i*PI/6);
                ctx.beginPath();  
                ctx.moveTo(0,-287);
                ctx.lineTo(0,-278); 
                ctx.closePath();  
                ctx.stroke();  
                ctx.restore();  
            }

            //时针  
            ctx.save();           
            ctx.lineWidth=3;                  
            ctx.strokeStyle="#0f0f0f";                
            ctx.translate(300,300);
            ctx.rotate(hour*PI/6+second*PI/108000);  
            ctx.beginPath();  
            ctx.moveTo(0,-238);
            ctx.lineTo(0,10);  
            ctx.closePath();  
            ctx.stroke();  
            ctx.restore();  

            //分针  
            ctx.save();  
            ctx.lineWidth=3;  
            ctx.strokeStyle="#010101";  
            ctx.translate(300,300);  
            ctx.rotate(Minute*PI/30+second*PI/1800);  
            ctx.beginPath();  
            ctx.moveTo(0,-258);  
            ctx.lineTo(0,15);  
            ctx.closePath();  
            ctx.stroke();
            ctx.restore();  


            //秒针              
            ctx.save();  
            ctx.strokeStyle="#ff100d";  
            ctx.lineWidth=3;  
            ctx.translate(300,300);               
            ctx.rotate(second*PI/30);               
            ctx.beginPath();
            ctx.moveTo(0,-278);  
            ctx.lineTo(0,20);  
            ctx.closePath();  
            ctx.stroke();  

            ctx.beginPath();                        //时针分针秒针交点  
            ctx.arc(0,0,6,0,2*PI,false);
            ctx.closePath();                  
            ctx.fillStyle="#fff";
            ctx.fill();               
            ctx.stroke();     
            ctx.restore();  
            requestAnimationFrame(drawBig);            //实现动画修改的接口
        };
        drawBig();
        setInterval(drawBig,1000);                    //每1s重绘一次
    };
    return{
        canvasClock:_canvasClock,
    }
}())

三 、整数算法

 

2.2 RGB转YUV
  从分析YUV转库罗德GB时,我们发现了四个首要全面——与U有关的2.032 和
与V有关的1.140。所以大家拿它们去乘安德拉GB转YUV转换矩阵的周全试试:
U: 2.032 * [-0.148 -0.289  0.437] = [-0.300736 -0.587248 
0.887984]
V: 1.140 * [ 0.615 -0.515 -0.100] = [ 0.701100 -0.587100 -0.114000]

今日在群里看外人发了一手表的图片,卧槽…妥妥的做事好多年的点子,后来考虑依旧做好本人的事体算了,想那多干啥,就画了二个手表….

  YUV转GL450GB的更换是那样的:
[R] = [1  0      1.140]   [Y]
[G] = [1 -0.395 -0.581] * [U]
[B] = [1  2.032  0    ]   [V]

 

  阅览那一个周全,发现有三个性子:
  1.那多少个负数周密与“彩色转灰度”周密(0.29玖 、0.58⑦ 、0.114)很相似。
  2.越发正数全面 正好等于 七个负数周全之和的相对值。

html

  YUV转RGB:
B = Y + 2.032*U
R = Y + 1.140*V
G = Y – (0.114*2.032 / 0.587)*U – (0.299*1.140 / 0.587)*V

 

  利用“Y = 0.299*R + 0.587*G + 0.114*B”那些实际来推导G:
G = (Y – 0.299*R – 0.114*B) / 0.587

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>canvas clock</title>
        <script type="text/javascript" src="percent.js"></script>
    </head>
    <body>
        <canvas id="canvas" width="600" height="600"></canvas>
    </body>
</html>
<script type="text/javascript">
    clock.canvasClock();
</script>

  所谓的YUV色彩模型是由0.29九 、0.58七 、0.11肆 、2.03贰 、1.140那几个数字定义出来的,相当简短、精巧。可是那还不是最精细的,YCbCr完全是由0.29⑨ 、0.587、0.114那八个数字定义出来的,详见《深刻学习Ycbcr色彩模型》。

B = Y + YUV_U2B[0x100 + U]
R = Y + YUV_V2R[0x100 + V]
G = Y – ((YUV_U2G[0x100 + U] + YUV_V2G[0x100 + V]) >> 16)

一、基础

  EscortGB转YUV的更换是这样的:
[Y] = [ 0.299  0.587  0.114]   [R]
[U] = [-0.148 -0.289  0.437] * [G]
[V] = [ 0.615 -0.515 -0.100]   [B]

  起首以YUV转PAJEROGB为突破口。注意在更换矩阵中有多个0,所以能够去掉2回乘法:
B = Y + 2.032*U
R = Y + 1.140*V

  先将近年来的名堂列出来。
  RGB转YUV:
Y = 0.299*R + 0.587*G + 0.114*B
U = (1 / 2.032)*(B-Y)
V = (1 / 1.140)*(R-Y)

  用矩阵总计“奇骏GB转YUV”一点也不快,我们可依据“YUV转索罗德GB”逆推:
Y = 0.299*R + 0.587*G + 0.114*B
U = (1 / 2.032)*(B-Y)
V = (1 / 1.140)*(R-Y)

 

  最早先,笔者是想找一个TiguanGB与YUV转换的急快速总括法,于是开头琢磨它的全面。

  将B、汉兰达的总结公式代入并化简:
G = [Y – 0.299*(Y + 1.140*V) – 0.114*(Y + 2.032*U)] / 0.587
  = [Y – (0.299*Y + 0.299*1.140*V) – (0.114*Y + 0.114*2.032*U)]
/ 0.587
  = [(Y – 0.299*Y – 0.114*Y)- 0.299*1.140*V – 0.114*2.032*U] /
0.587
  = [(1 – 0.299 – 0.114)*Y – 0.299*1.140*V – 0.114*2.032*U] /
0.587
  = (0.587*Y – 0.299*1.140*V – 0.114*2.032*U) / 0.587
  = Y + (-0.299*1.140*V – 0.114*2.032*U) / 0.587
  = Y – (0.299*1.140 / 0.587)*V – (0.114*2.032 / 0.587)*U
  = Y – (0.114*2.032 / 0.587)*U – (0.299*1.140 / 0.587)*V
  = Y – 0.394630*U – 0.580681*V

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图