gpt4 book ai didi

javascript - 在 Javascript 中使用渐变方向来引导笔触效果

转载 作者:搜寻专家 更新时间:2023-11-01 04:31:31 26 4
gpt4 key购买 nike

我正在尝试用 Javascript(特别是使用 p5.js)重新创建其他人似乎已使用 Mathematica 套件成功实现的效果,如此处所示 https://mathematica.stackexchange.com/a/39049 .

我 100% 不知道 Mathematica,但我看到他们正在使用一种名为 GradientOrientationFilter 的方法来创建遵循图像渐变方向的笔划图案。

oil brushes

我的结果仍然不令人满意。

我正在尝试的逻辑

  • 创建方向梯度直方图,评估亮度值,然后找出水平和垂直梯度及其方向和大小;
  • 在每个像素处绘制一条线,用随机灰度颜色表示渐变方向。稍后我将使用这些线条,与实际图片混合。

代码:

var img, vectors;

var pixelsToSkip = 2; // for faster rendering we can stroke less lines
var linesLength = 20;
var strokeThickness = 1;

function preload() {
img = loadImage('http://lorempixel.com/300/400/people/1');
img2 = loadImage('http://lorempixel.com/300/400/people/1');

/* you can test in local if the directions are correct using a simple gradient as image
img = loadImage('http://fornace.io/jstests/img/gradient.jpg');
img2 = loadImage('http://fornace.io/jstests/img/gradient.jpg');
*/
}

function setup() {
createCanvas(img.width, img.height);
noLoop();
img.loadPixels();


makeLumas();
makeGradients();
makeVectors();

for ( var xx = 0; xx < img.width; xx = xx + pixelsToSkip) {
for ( var yy = 0; yy < img.height; yy = yy + pixelsToSkip) {
push();
stroke(random(255)); // to color with pixel color change to stroke(img.get(xx, yy));
strokeWeight(strokeThickness);
translate(xx,yy);
rotate( vectors[yy][xx].dir ); // here we use the rotation of the gradient
line(-linesLength/2, 0, linesLength/2, 0);
pop();
}
}

// adding the image in overlay to evaluate if the map is good
// tint(255, 255, 255, 100);
// image(img2,0,0);


}

function draw() {
}




function makeLumas() {
// calculate the luma for each pixel to get a map of dark/light areas ("Rec. 601") https://en.wikipedia.org/wiki/Luma_(video)
lumas = new Array(img.height);
for (var y = 0; y < img.height; y++) {
lumas[y] = new Array(img.width);

for (var x = 0; x < img.height; x++) {
var i = x * 4 + y * 4 * img.width;
var r = img.pixels[i],
g = img.pixels[i + 1],
b = img.pixels[i + 2],
a = img.pixels[i + 3];

var luma = a == 0 ? 1 : (r * 299/1000 + g * 587/1000
+ b * 114/1000) / 255;

lumas[y][x] = luma;
}
}
}

function makeGradients() {
// calculate the gradients (kernel [-1, 0, 1])

var horizontalGradient = verticalGradient = [];

for (var y = 0; y < img.height; y++) {
horizontalGradient[y] = new Array(img.width);
verticalGradient[y] = new Array(img.width);

var row = lumas[y];

for (var x = 0; x < img.width; x++) {
var prevX = x == 0 ? 0 : lumas[y][x - 1];
var nextX = x == img.width - 1 ? 0 : lumas[y][x + 1];
var prevY = y == 0 ? 0 : lumas[y - 1][x];
var nextY = y == img.height - 1 ? 0 : lumas[y + 1][x];

horizontalGradient[y][x] = -prevX + nextX;
verticalGradient[y][x] = -prevY + nextY;
}
}
}

function makeVectors() {
// calculate direction and magnitude

vectors = new Array(img.height);

for (var y = 0; y < img.height; y++) {
vectors[y] = new Array(img.width);

for (var x = 0; x < img.width; x++) {
var prevX = x == 0 ? 0 : lumas[y][x - 1];
var nextX = x == img.width - 1 ? 0 : lumas[y][x + 1];
var prevY = y == 0 ? 0 : lumas[y - 1][x];
var nextY = y == img.height - 1 ? 0 : lumas[y + 1][x];

var gradientX = -prevX + nextX;
var gradientY = -prevY + nextY;

vectors[y][x] = {
mag: Math.sqrt(Math.pow(gradientX, 2) + Math.pow(gradientY, 2)),
dir: Math.atan2(gradientY, gradientX)
}
}
}
}

图像上的结果

我用 javascript 制作的领域比用 Mathematica 制作的领域嘈杂得多。

http://jsfiddle.net/frapporti/b4zxkcmL/

results

最后的说明

我对 p5.js 很陌生,也许我在某些段落中重新发明了轮子。在这方面也请随时纠正我。

fiddle :http://jsfiddle.net/frapporti/b4zxkcmL/

最佳答案

模糊那些像素!

对我有用的解决方案是在任何像素分析之前简单地模糊以平滑梯度方向过滤器的结果。

如果您使用的是 p5.js,这可能与 img.filter("blur",5); 一样简单。否则,您可以使用您选择的任何其他模糊技术。

您可以在此处查看代码:http://jsfiddle.net/frapporti/b4zxkcmL/21/

如果有人有其他方法,我会等待,然后再将此答案标记为已接受。

enter image description here

关于javascript - 在 Javascript 中使用渐变方向来引导笔触效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26393131/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com