雾化(使用w分量)

<html>
<head>11</head>
<body>
<canvas id = "test" width = "800" height = "800">canvas </canvas>
<script src = "webgltest/cuon-matrix.js"></script>
<script >
//顶点着色器
var vertexShaderSource =
    'attribute vec4 a_Position;\n' +
    'attribute vec4 a_Color;\n' +
    'uniform mat4 u_mvpMatrix;\n' +
    'uniform mat4 u_ModelMatrix;\n' +                //模型矩阵
    'uniform vec4 u_Eye;\n' +
    'varying vec4 v_Color;\n' +                     //varying变量
    'varying float v_Dist;\n' +
    'void main() {\n' +
    'gl_Position =  u_mvpMatrix * a_Position;\n'+       
    'v_Color = a_Color;\n' +                                         //将数据传给片元着色器
    //计算顶点与视点的距离(<1)
    'v_Dist = gl_Position.w;\n' +
    '}\n';

//片元着色器
var fragmentShaderSource =
    'precision mediump float;\n' +
    'uniform vec3 u_FogColor; \n' +                    //雾的颜色
    'uniform vec2 u_FogDist; \n' +                    //雾化的起点和终点
    'varying vec4 v_Color;\n' +                     //varying变量
    'varying float v_Dist;\n' +
    'void main() {\n' +        
    //计算雾化因子
    'float fogFactor = clamp((u_FogDist.y - v_Dist ) / (u_FogDist.y - u_FogDist.x ), 0.0, 1.0 ); \n' +
    'vec3 color = mix(u_FogColor, vec3(v_Color), fogFactor); \n' +
    'gl_FragColor = vec4(color, v_Color.a); \n' +
    '}\n';

//创建着色器方法,输入参数:渲染上下文,着色器类型,数据源
function createShader(gl, type, source)
{
    //创建着色器对象
    var shader = gl.createShader(type);
    //提供数据源
    gl.shaderSource(shader,source);
    //编译着色器
    gl.compileShader(shader);
    //链接
    var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if(success)
    {
        return shader;
    }
    console.log(gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    
}
//将顶点着色器和像素着色器链接到一个着色程序
function createProgram(gl, vertexShader, fragmentShader)
{
    var program = gl.createProgram();
    gl.attachShader( program, vertexShader);
    gl.attachShader( program, fragmentShader);
    gl.linkProgram( program );
    var success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if(success)
    {
        console.log("link right");
        return program;
    }
    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
}

//创建顶点缓冲区和索引缓冲区


function initVertexBuffers(program,gl) {
  // Create a cube
  //    v6----- v5
  //   /|      /|
  //  v1------v0|
  //  | |     | |
  //  | |v7---|-|v4
  //  |/      |/
  //  v2------v3

  var vertices = new Float32Array([   // Vertex coordinates
     1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,  // v0-v1-v2-v3 front
     1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,  // v0-v3-v4-v5 right
     1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,  // v0-v5-v6-v1 up
    -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,  // v1-v6-v7-v2 left
    -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,  // v7-v4-v3-v2 down
     1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0   // v4-v7-v6-v5 back
  ]);
 
  var colors = new Float32Array([    // Colors
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v1-v2-v3 front
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v3-v4-v5 right
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v5-v6-v1 up
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v1-v6-v7-v2 left
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v7-v4-v3-v2 down
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0     // v4-v7-v6-v5 back
 ]);

  var normals = new Float32Array([    // Normal
    0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
    1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
    0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
   -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
    0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,  // v7-v4-v3-v2 down
    0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0   // v4-v7-v6-v5 back
  ]);
 
  var indices = new Uint8Array([       // Indices of the vertices
     0, 1, 2,   0, 2, 3,    // front
     4, 5, 6,   4, 6, 7,    // right
     8, 9,10,   8,10,11,    // up
    12,13,14,  12,14,15,    // left
    16,17,18,  16,18,19,    // down
    20,21,22,  20,22,23     // back
  ]);

  // Create a buffer object
  var indexBuffer = gl.createBuffer();
  if (!indexBuffer)
    return -1;

  // Write the vertex coordinates and color to the buffer object
  if (!initArrayBuffer(program,gl, vertices, 3, gl.FLOAT, 'a_Position'))
    return -1;

  if (!initArrayBuffer(program,gl, colors, 3, gl.FLOAT, 'a_Color'))
    return -1;

  // Write the indices to the buffer object
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

  return indices.length;
}

function initArrayBuffer(program, gl, data, num, type, attribute) {
  var buffer = gl.createBuffer();   // Create a buffer object
  if (!buffer) {
    console.log('Failed to create the buffer object');
    return false;
  }
  // Write date into the buffer object
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
  // Assign the buffer object to the attribute variable
  var a_attribute = gl.getAttribLocation(program, attribute);
  if (a_attribute < 0) {
    console.log('Failed to get the storage location of ' + attribute);
    return false;
  }
  gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
  // Enable the assignment of the buffer object to the attribute variable
  gl.enableVertexAttribArray(a_attribute);

  return true;
}
    var canvas = document.getElementById("test");
    //创建webgl渲染上下文
    var gl = canvas.getContext("webgl");
    //var gl = WebGLUtils.setupWebGL(canvas);
    if(!gl)
    {
        console.log("wrong");
    }
    else
    {
        console.log("right");
    }
    //初始化着色器

    var vertexShader = createShader(gl,gl.VERTEX_SHADER,vertexShaderSource);
    var fragmentShader = createShader(gl,gl.FRAGMENT_SHADER, fragmentShaderSource);
    var program = createProgram(gl, vertexShader, fragmentShader);
    gl.useProgram(program);
    //创建顶点数组
    var n = initVertexBuffers(program,gl);
 
    //雾的颜色
    var fogColor = new Float32Array([0.137, 0.231, 0.423]);
    //雾化的起点和终点与视点间的距离[起点距离,终点距离]
    var fogDist = new Float32Array([55, 80]);
    //视点在世界坐标系下的坐标
    var eye = new Float32Array([25, 65,35, 1.0]);
    
    //获取投影矩阵
    var u_mvpMatrix = gl.getUniformLocation(program, 'u_mvpMatrix');
    var u_ModelMatrix = gl.getUniformLocation(program, 'u_ModelMatrix');
    //雾的参数
    var u_FogColor = gl.getUniformLocation(program, 'u_FogColor');
    var u_FogDist = gl.getUniformLocation(program, 'u_FogDist');
    var u_Eye = gl.getUniformLocation(program, 'u_Eye');
    
    if (!u_mvpMatrix || !u_ModelMatrix || !u_Eye || !u_FogColor || !u_FogDist) {
    console.log('Failed to get the storage location');
   
    }
    //设置雾的颜色、起点与终点、视点坐标传给相应的Uniform变量
    gl.uniform3fv(u_FogColor, fogColor);
    gl.uniform2fv(u_FogDist, fogDist);
    gl.uniform4fv(u_Eye, eye);
    //清除颜色
    //在绘制之前,清除深度缓冲区
    gl.clearColor(fogColor[0], fogColor[1], fogColor[2], 1.0);
    //开启隐藏面消除功能
    gl.enable(gl.DEPTH_TEST);
        
    //模型矩阵
    var modelMatrix = new Matrix4();
    modelMatrix.setScale(10, 10, 10);
    gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
        
    var g_near = 1.0, g_far = 1000.0;
    //模型视图投影矩阵
    var mvpMatrix = new Matrix4();
    mvpMatrix.setPerspective(30, canvas.width / canvas.height,g_near, g_far);
    mvpMatrix.lookAt(eye[0], eye[1], eye[2], 0, 2, 0, 0, 1, 0 );
    mvpMatrix.multiply(modelMatrix);
    //将投影矩阵传给u_ProjMatrix变量
    gl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrix.elements);
    
    
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    //绘制正方体
    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0 );
    
    </script>
</body>
</html>

以下是一种基于暗通道先验的图像去雾算法的MATLAB实现: ```matlab function J = dehaze(I, t0, w) % I:输入图像 % t0:暗通道先验阈值 % w:大气光强度权重参数 % 转换为double类型 I = im2double(I); % 计算暗通道图像 J_dark = dark_channel(I, 15); % 估计大气光强度 A = estimate_airlight(I, J_dark, w); % 计算透射率 t = transmission(I, A, t0); % 对图像进行修复 J = recover(I, A, t); % 显示结果 imshow([I, J], 'border', 'tight'); end function J_dark = dark_channel(I, w_size) % 计算暗通道图像 % 计算最小值滤波 J_dark = ordfilt2(I(:,:,1), 1, ones(w_size, w_size)); for i = 2:size(I,3) J_dark = min(J_dark, ordfilt2(I(:,:,i), 1, ones(w_size, w_size))); end end function A = estimate_airlight(I, J_dark, w) % 估计大气光强度 % 将暗通道图像按照像素值大小排序 J_dark_vec = reshape(J_dark, [], 1); J_dark_sorted = sort(J_dark_vec, 'descend'); % 选择暗通道像素值最大的前0.1%作为大气光强度估计 n_pixels = numel(J_dark_vec); n_top = round(n_pixels * 0.001); top_val = mean(J_dark_sorted(1:n_top)); % 根据权重参数调整估计值 A = w * top_val + (1 - w) * mean(I(:)); end function t = transmission(I, A, t0) % 计算透射率 % 计算归一化的透射率 t = 1 - t0 * dark_channel(I ./ A, 15); % 截断透射率 t = max(t, 0.1); end function J = recover(I, A, t) % 对图像进行修复 % 估计场景中反射分量的平均亮度 J_mean = mean(I(t > 0.1)); % 根据透射率和大气光强度进行修复 J = (I - A) ./ max(t, 0.1) + A - (J_mean - A) * (1 - t); end ``` 该算法的输入为一张雾化图像,需要指定暗通道先验阈值`t0`和大气光强度权重参数`w`,输出为去雾后的图像。算法包含以下步骤: 1. 计算暗通道图像。 2. 估计大气光强度。 3. 计算透射率。 4. 对图像进行修复。 其中,暗通道图像是指在一张图像中,每个局部区域内最暗的像素值组成的图像。暗通道先验假设在没有雾的情况下,暗通道图像的值应该非常小,因此可以用来估计大气光强度。透射率则是指光线在穿过雾时被吸收的程度,透射率越低,雾就越浓。修复的过程则是根据透射率和大气光强度对图像进行反向操作,从而去除雾霾的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值