Алгоритмы фильтрации для обработки изображений

внешний интерфейс алгоритм
Алгоритмы фильтрации для обработки изображений

Фильтр оттенков серого

Установка того же значения для RGB цвета может сделать изображение серым.Общие методы обработки следующие: 1. Возьмите среднее значение трех цветов. 2. Возьмите максимальное значение (минимальное значение) трех цветов 3. Средневзвешенный: 0,3R + 0.59G + 0.11*B

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;
}

image.png

черно-белый фильтр

Как следует из названия, цвет изображения только черно-белый, и можно вычислить средний аргумент rgb, arg>=100, r=g=b=255, иначе он равен 0

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;
}

image.png

Инвертировать фильтр

То есть разница между тремя цветами RGB составляет 255.

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];
}

image.png

Обесцвечивающий фильтр

Три цвета rgb берут среднее значение большинства значений трех цветов.

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

for(var i = 0; i < canvas.height * canvas.width; i++) {
    data[i*4 + 2] = 0;
    data[i*4 + 1] = 0;
}

Фильтр размытия по Гауссу

Принцип размытия по Гауссу заключается в том, чтобы сделать веса пикселей вокруг каждого пикселя несовместимыми в соответствии с нормальным распределением, умножить каждый вес (сумма каждого значения веса равна 1) и соответствующее значение цвета, а сумма результатов равна новый центральный пиксель значение цвета. Формула размытия по Гауссу, которую нам нужно знать:

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;
}

ностальгический фильтр

Формула фильтра ностальгии

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;
}

Плавленый фильтр

формула: р = р128/(g+b +1); g = g128/(r+b +1); b = b*128/(g+r +1);

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;
}

image.png

Заморозить фильтр

формула: r = (r-g-b)*3/2; г = (г-р-б)*3/2; б = (б-г-г)*3/2;

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;

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;
}

image.png

Сепия фильтр

формула: г = г * 0,393 + г * 0,769 + б * 0,189; г = г * 0,349 + г * 0,686 + б * 0,168; б = г * 0,272 + г * 0,534 + б * 0,131;

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 * 0.393 + g * 0.769 + b * 0.189;
    var newG = r * 0.349 + g * 0.686 + b * 0.168;
    var newB =  r * 0.272 + g * 0.534 + b * 0.131;
    var rgbArr = [newR, newG, newB];
    [imgData.data[i * 4], imgData.data[i * 4 + 1], imgData.data[i * 4 + 2]] = rgbArr;
}

image

Последний рекламный пост.Недавно открылся новый публичный аккаунт для обмена технологиями.Не знаю сколько он продлится.Приглашаю всех обратить внимание👇