图像处理的滤镜算法

2019-07-24 14:17:29 浏览数 (2)

灰度滤镜

将颜色的RGB设置为相同的值即可使得图片为灰色,一般处理方法有: 1、取三种颜色的平均值 2、取三种颜色的最大值(最小值) 3、加权平均值:0.3R 0.59G 0.11*B

代码语言:javascript复制
for(var i = 0; i < data.length; i =4) {
     var grey = (data[i]   data[i 1]   data[i 2]) / 3;
     data[i] = data[i 1] = data[i 2] = grey;
}

黑白滤镜

顾名思义,就是图片的颜色只有黑色和白色,可以计算rgb的平均值arg,arg>=100,r=g=b=255,否则均为0

代码语言:javascript复制
for(var i = 0; i < data.length; i  = 4) {
     var avg = (data[i]   data[i 1]   data[i 2]) / 3;
     data[i] = data[i 1] = data[i 2] = avg >= 100 ? 255 : 0;
}

反向滤镜

就是RGB三种颜色分别取255的差值。

代码语言:javascript复制
for(var i = 0; i < data.length; i = 4) {
      data[i] = 255 - data[i];
      data[i   1] = 255 - data[i   1];
      data[i   2] = 255 - data[i   2];
}

去色滤镜

rgb三种颜色取三种颜色的最值的平均值。

代码语言:javascript复制
for(var i = 0; i < data.length; i  ) {
   var avg = Math.floor((Math.min(data[i], data[i 1], data[i 2])   Math.max(data[i], data[i 1], data[i 2])) / 2 );
   data[i] = data[i 1] = data[i 2] = avg;
}

单色滤镜

就是只保留一种颜色,其他颜色设为0

代码语言:javascript复制
for(var i = 0; i < canvas.height * canvas.width; i  ) {
    data[i*4   2] = 0;
    data[i*4   1] = 0;
}

高斯模糊滤镜

高斯模糊的原理就是根据正态分布使得每个像素点周围的像素点的权重不一致,将各个权重(各个权重值和为1)与对应的色值相乘,所得结果求和为中心像素点新的色值。我们需要了解的高斯模糊的公式:

代码语言:javascript复制
function gaussBlur(imgData, radius, sigma) {
    var pixes = imgData.data,
        height = imgData.height,
        width = imgData.width,
        radius = radius || 5;
        sigma = sigma || radius / 3;
    
    var gaussEdge = radius * 2   1;

    var gaussMatrix = [],
        gaussSum = 0,
        a = 1 / (2 * sigma * sigma * Math.PI),
        b = -a * Math.PI;
    
    for(var i = -radius; i <= radius; i  ) {
        for(var j = -radius; j <= radius; j  ) {
            var gxy = a * Math.exp((i * i   j * j) * b);
            gaussMatrix.push(gxy);
            gaussSum  = gxy;
        }
    }
    var gaussNum = (radius   1) * (radius   1);
    for(var i = 0; i < gaussNum; i  ) {
        gaussMatrix[i] /= gaussSum;
    }

    for(var x = 0; x < width; x  ) {
        for(var y = 0; y < height; y  ) {
            var r = g = b = 0;
            for(var i = -radius; i<=radius; i  ) {
                var m = handleEdge(i, x, width);
                for(var j = -radius; j <= radius; j  ) {
                    var mm = handleEdge(j, y, height);
                    var currentPixId = (mm * width   m) * 4;
                    var jj = j   radius;
                    var ii = i   radius;
                    r  = pixes[currentPixId] * gaussMatrix[jj * gaussEdge   ii];
                    g  = pixes[currentPixId   1] * gaussMatrix[jj * gaussEdge   ii];
                    b  = pixes[currentPixId   2] * gaussMatrix[jj * gaussEdge   ii];
                }
            }
            var pixId = (y * width   x) * 4;

            pixes[pixId] = ~~r;
            pixes[pixId   1] = ~~g;
            pixes[pixId   2] = ~~b;
        }
    }
    imgData.data = pixes;
    return imgData;
}

function handleEdge(i, x, w) {
    var m = x   i;
    if(m < 0) {
        m = -m;
    } else if(m >= w) {
        m = w   i -x;
    }
    return m;
}

怀旧滤镜

怀旧滤镜公式

代码语言:javascript复制
for(var i = 0; i < imgData.height * imgData.width; i  ) {
    var r = imgData.data[i*4],
        g = imgData.data[i*4 1],
        b = imgData.data[i*4 2];

    var newR = (0.393 * r   0.769 * g   0.189 * b);
    var newG = (0.349 * r   0.686 * g   0.168 * b);
    var newB = (0.272 * r   0.534 * g   0.131 * b);
    var rgbArr = [newR, newG, newB].map((e) => {
        return e < 0 ? 0 : e > 255 ? 255 : e;
    });
    [imgData.data[i*4], imgData.data[i*4 1], imgData.data[i*4 2]] = rgbArr;
}

熔铸滤镜

公式: r = r128/(g b 1); g = g128/(r b 1); b = b*128/(g r 1);

代码语言:javascript复制
for(var i = 0; i < imgData.height * imgData.width; i  ) {
    var r = imgData.data[i*4],
        g = imgData.data[i*4 1],
        b = imgData.data[i*4 2];

    var newR = r * 128 / (g   b   1);
    var newG = g * 128 / (r   b   1);
    var newB = b * 128 / (g   r   1);
    var rgbArr = [newR, newG, newB].map((e) => {
        return e < 0 ? 0 : e > 255 ? 255 : e;
    });
    [imgData.data[i*4], imgData.data[i*4 1], imgData.data[i*4 2]] = rgbArr;
}

冰冻滤镜

公式: r = (r-g-b)*3/2; g = (g-r-b)*3/2; b = (b-g-r)*3/2;

代码语言:javascript复制
for(var i = 0; i < imgData.height * imgData.width; i  ) {
    var r = imgData.data[i*4],
        g = imgData.data[i*4 1],
        b = imgData.data[i*4 2];

    var newR = (r - g -b) * 3 /2;
    var newG = (g - r -b) * 3 /2;
    var newB = (b - g -r) * 3 /2;
    var rgbArr = [newR, newG, newB].map((e) => {
        return e < 0 ? 0 : e > 255 ? 255 : e;
    });
    [imgData.data[i*4], imgData.data[i*4 1], imgData.data[i*4 2]] = rgbArr;
}

连环画滤镜

公式: R = |g – b g r| * r / 256

G = |b – g b r| * r / 256;

B = |b – g b r| * g / 256;

代码语言:javascript复制
for(var i = 0; i < imgData.height * imgData.width; i  ) {
    var r = imgData.data[i*4],
        g = imgData.data[i*4 1],
        b = imgData.data[i*4 2];

    var newR = Math.abs(g - b   g   r) * r / 256;
    var newG = Math.abs(b -g   b   r) * r / 256;
    var newB =  Math.abs(b -g   b   r) * g / 256;
    var rgbArr = [newR, newG, newB];
    [imgData.data[i*4], imgData.data[i*4 1], imgData.data[i*4 2]] = rgbArr;
}
rgb

0 人点赞