Выравнивание гистограммы изображения p5.js - PullRequest
2 голосов
/ 27 сентября 2019

Легко blend() два изображения, используя p5.js, и это здорово, но я бы хотел выровнять гистограмму полученного смешанного изображения.Что-то вроде -equalize в ImageMagick.Кто-нибудь знает, как это сделать в p5.js?

1 Ответ

1 голос
/ 27 сентября 2019

Вы можете сделать это, конечно.Алгоритм: Для каждого канала рассчитайте кумулятивные нормализованные гистограммы, умноженные на максимальное значение в этом канале - это будут ваши новые значения пикселей в канале с учетом старого значения.
Я прочитал описание алгоритма на GeeksforGeeks портале и перенесенэто к p5.js, код:

let img
let mod

// helpers
function getMappings() {
 hists = [[], [], []];
 newlevels = [[], [], []];
 maxval = [-1, -1, -1];
 // RGB histograms & maximum pixel values
 for (let i = 0; i < img.width; i++) {
  for (let j = 0; j < img.height; j++) {
    let c = img.get(i, j);
    hists[0][c[0]] = (hists[0][c[0]] || 0) + 1;
    hists[1][c[1]] = (hists[1][c[1]] || 0) + 1;
    hists[2][c[2]] = (hists[2][c[2]] || 0) + 1;
    for (let ch=0; ch < 3; ch++) {
      if (c[ch] > maxval[ch]) {
         maxval[ch] = c[ch];
      }
    }
  }
 }
 // New intensity levels based on cumulative, normalized histograms
 for (let hi = 0; hi < 3; hi++) {
   let acc = 0;
   for (let lev=0; lev < 256; lev++) {
      acc += hists[hi][lev];
      newlevels[hi][lev] = Math.round(maxval[hi]*acc/(img.width*img.height));
   }
 }
 return newlevels;
}

function equalizeHistograms() {
  let map = getMappings();
  for (let i = 0; i < mod.width; i++) {
   for (let j = 0; j < mod.height; j++) {
     let c = img.get(i, j);
     let newcol = color(map[0][c[0]], map[1][c[1]], map[2][c[2]]);
     mod.set(i, j, newcol);
   }
  }
  mod.updatePixels();
}

// system functions

function preload() {
  img = loadImage('https://i.imgur.com/00HxCYr.jpg');
  mod = createImage(200, 140);
}

function setup() {
  img.loadPixels();
  mod.loadPixels();
  createCanvas(250, 400);
  equalizeHistograms();
}

function draw() {
  image(img,0,0);
  image(mod,0,140);
}

DEMO

...