p5.js图像直方图均衡化
p5.js image histogram equalization
使用 p5.js 可以很容易地 blend()
两个图像,这很好,但我希望能够均衡生成的混合图像的直方图。类似于 ImageMagick 中的 -equalize
。有谁知道如何在 p5.js 中执行此操作?
当然可以。算法:对于每个通道,计算累积归一化直方图乘以该通道中的最大值 - 这将是给定旧值的通道中的新像素值。
我已经阅读 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);
}
使用 p5.js 可以很容易地 blend()
两个图像,这很好,但我希望能够均衡生成的混合图像的直方图。类似于 ImageMagick 中的 -equalize
。有谁知道如何在 p5.js 中执行此操作?
当然可以。算法:对于每个通道,计算累积归一化直方图乘以该通道中的最大值 - 这将是给定旧值的通道中的新像素值。
我已经阅读 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);
}