Edge Detection Objects List

djlbe's icon

Hi,

Since I'm doing some experimentations with a patch that use Edge Detection, I'm trying to list objects that allow it under jitter.
Reading that forum and searching across internet I found these :
-cv.jit.canny
-cv.jit.binedge
-jit.robcross
-jit.sobel,...

Did you know other objects / jit.gen patch / Abstraction ? Which the best one ?

+Some people talk about xray collection on c74 forum, I've it but I can't find any object inside that permit edge dectection, any idea?

Andro's icon

Surprisingly few !
Even if only one do's the job well then I suppose its okay.

djlbe's icon

There is that method that seems really cool for exemple. :
http://www.ipol.im/pub/art/2012/gjmr-lsd/?utm_source=doi

Andro's icon

I think that jit.gl.slab
cf.sobel.jxs-help.maxpat
Will be faster than jit.sobel as its processed on the GPU

djlbe's icon

or jit.gl.pix ?

Andro's icon

Should be possible to convert the shader to jit.gl.pix, just not too sure how the
texcoord 00
texcoord 02
and so on work...

djlbe's icon

I think that it works like jit.pix or jit.gen right? you use cell, norm and snorm as coords ? not sure, I don't know jxs and slab usage very well

But that's weird that there is 'only' four objects about edge detection, I can't beleive it :(.
There should be somewhere a secret jitter librairy for it

Andro's icon

In1 uses the incoming matrix not normalized co-ordinates.

syrinx's icon

There are a bunch of shaders over at Shadertoy that take camera input and do various flavours of edge detection:

I wasn't able to get these to read the webcam in Chrome, but they worked fine in Firefox - YMMV.

I'm still trying to learn enough GLSL to port these for Jitter use, but if I do manage it, I'll post them here!

syrinx's icon

Oops - that middle one isn't an edge detection shader... but it is nice!

syrinx's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Here's the Sobel one:

syrinx's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Here's the Roberts one:

I would appreciate it if someone could take a look at this and see if it can't be made a bit more efficient. In the original shader, the function "bw" is used four times in defining the output value ("bwColor"). In Gen, repeating bw within the definition of bwColor causes a whole slew of errors:

lua_docall error: [string "gen2.jit.Model"]:437: assertion failed!
stack traceback:
    [C]: in function 'assert'
    [string "gen2.jit.Model"]:437: in function 'Function'
    [string "gen2.jit.Model"]:586: in function 'process_operator_instance'
    [string "gen2.jit.Model"]:685: in function 'Expression'
    [string "gen2.jit.Model"]:697: in function 'f'
    [string "gen2.Module"]:862: in function 'flow_iterate'
    [string "gen2.Module"]:860: in function 'flow_iterate'
    [string "gen2.Module"]:860: in function 'flow_iterate'

My workaround for this was to create four separate, identical bw functions (named bw1-bw4). It seems like there should be a tidier way of doing this, but I don't know what it is. Any tips as to better solutions (and information about why repeating bw causes those errors) would be greatly appreciated!

SID's icon

Really great job, Syrinx. You say you are only learning GLSL? I'm getting nowhere with what I'm trying to do. I can't even get the shadertoy code into a jsx file so that jit.slab can read it. See: https://cycling74.com/forums/importing-shadertoy-code-into-codebox-help-needed/
What's your secret?

Rob Ramirez's icon

hi syrinx, i can't reproduce your errors with using the same function.
your code looks good. here's a couple notes:
you can use norm in place of cell / dim (simply a convenience, won't affect efficiency)
you can use fastpow in place of pow (as implied by the name, should be faster)

bw1(coords){
    lm1 = sample(in1, coords) * vec(0.21, 0.71, 0.07, 1.0);
    return lm1.r + lm1.g + lm1.b;
}

uv = norm;

of = vec(1.0 / 128.0, 0.0);

bwColor = sqrt(fastpow(abs(bw1(uv) - bw1(uv + of.xx)), 2.0) + fastpow(abs(bw1(uv + of.xy) - bw1(uv + of.yx)), 2.0));
out1 = bwColor;

syrinx's icon

Thanks, Rob! Sorry for the belated reply - got distracted by other projects for a while. Not sure what I was fouling up before, but your code runs fine for me now.

Sid, there's no secret - it's just trial and error for me so far, combined with a bit of reading. The GenExpr documentation page as well as that GLSL tutorial on Shadertoy that you linked to in your other post have both been useful, and Andrew Benson's Your First Shader" tutorial has also been good in terms of getting my head around per-pixel processing in general. I recently found The Book of Shaders by Patricio Gonzalez Vivo, which has been incredibly useful - not least because it has the best online GLSL editor I've seen so far. The fact that the editor includes breakpoints for checking what's happening with variables at different points in the code makes it a great learning resource - try clicking on "color," "grid1," or "grid2" in the link to see what I mean.

I'm still very much flailing my way through both GLSL and Gen, and am finding that porting Shadertoy stuff is a good way of getting familiar with both. The first thing that I do is change the syntax over from Shadertoy's implementation of GLSL to Gen, which mostly involves deleting or replacing certain terms (Gen masters, please feel free to correct my explanations):

vec2, vec3, vec4, etc. : replace with vec.
In GLSL, you have to specify how many components a vector has. Gen uses the vec constructor for all vectors, which automatically recognizes how many components it's dealing with and adapts. For example, vec(in1.r,in1.g) in Gen is implicitly a vec2.)

float : can be removed.
In the same spirit as with vectors, GLSL requires you to specify data types, including floats, when instantiating variables. In Gen, this isn't necessary. Whereas in GLSL, you'd have to say "float a = 1.0;", in Gen it's adequate to say "a = 1.0;".

fragCoord.xy / iResolution.xy : replace with norm.
Normalized coordinates running from 0. to 1., given by dividing the current pixel's coordinates by the total resolution of the texture being processed. When fed to a sampler, this tells it "look at the current pixel."

fragCoord : replace with cell.
This is the current pixel's coordinates in absolute/non-normalized values. For a pixel located at x=100, y=100, cell would return (100, 100).

iResolution : replace with dim.
This returns the dimensions of the input texture. If you feed it a 1280x720 texture, dim will return (1280, 720).

texture2D : replace with sample.
Given an input and a set of spatial coordinates, this will grab and output pixel values. For example, sample(in1, norm) will give up pixel values from the first input according to normalized 0. to 1. coordinates, i.e. it'll give you your input in its original scale and orientation.

void mainImage( out vec4 fragColor, in vec2 fragCoord ){...} : can be removed.
The main image program is often enclosed inside of a mainImage function in Shadertoy shaders. This isn't necessary in Gen, so you can just take it out, along with the curly braces (but you'll need to keep the contents of the function!).

fragColor = vec4 : replace with out1 = [whatever];
fragColor often appears at the end of Shadertoy shaders as the final place that output pixel values are stored. If this is heading out of your Gen patcher for display, you can replace it with out1 (or out2, out3... etc., depending on your needs).

mat2(a,b,c,d) : can be replaced with vec(a+b, c+d) (maybe?)
I'm not totally sure about this one. Gen doesn't have native support for mat2, mat3, etc. (matrix) data types. I'm basing this substitution suggestion on a note from Graham Wakefield in this post (search for "apply a 3x3 matrix transform to a vec4"), but it's very possible that I'm misinterpreting what's going on here.

In general, without having any background in GLSL, I've been finding the Gen documentation a bit challenging to get into, and it wasn't until I went back to GLSL tutorials and learned about the per-pixel-processing paradigm that it began to make sense. If I ever get more of a handle on Gen, I would love to help produce some Gen tutorials that would be augured towards introducing n00bs like myself to GLSL fundamentals.