VOP Cop2 Filter workflow

   5215   15   1
User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
As much as I am comfortable working in wrangles in SOPland, using VOP Cop2 Filter network is a bit of a beast for me.

The setup I have works as is, but I would like to use the Max and Min nodes I have in the network too;

I want to use the single maximum and single minimum value of the red as the range of the fit nodes source inputs.

I'm assuming I can't just hook up the Max/Min nodes as the network is running over pixels in much the same way as what would happen in a point wrangle(run over points)?

Therefrom each pixel in this case has their Max/Min being the same as there is only one pixel being sampled for each iteration?

In SOPland I would get around something like this by first creating a detail attribute, from runnning in detail mode of a wrangle, and import that value to use as reference in the next wrangle.

Help is appreciated - Thanks.

P.S. The pic being used is the Houdini default butterfly so my hip should open for anyone looking at it.

Attachments:
VOP Cop2 Filter MaxMin node.hiplc (35.3 KB)

User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi,
this is from here:
http://www.sidefx.com/docs/houdini/composite/comp_vops.html [www.sidefx.com]

X,Y return the position of the current pixel in 0-1 notation. IX,IY return the position of the current pixel in 0 to XRES-1, 0 to YRES-1.
User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
Hi Olaf,

I'm not sure what your suggesting with that.

Yes I can get the position information, but that's not what I need.

I need the highest r value(or any other value like say luminance, etc.) out of the whole ‘array’ of pixels; their position is not important to me.

I tried again last night an approach to do a loop - but came to a dead end in how to create a ‘local’ variable that holds the result of a greater than compare operation.

But it appears you can't create local variables in VOPs; that can be modified during a loop. Unlike you can in a SOP wrangle.

Unless of course I can create an attribute before hand ( a previous VOP ) and wire that in as part of my loop input, doing an if/compare update of the attribute value.

Thanks for the reference though.
User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
i thought you had an issue with iterating over the pixels…
User Avatar
Member
7771 posts
Joined: Sept. 2011
Offline
There's no node to get the min/max value of an image plane in cops. You would need to write it yourself in C++, or using the python cop. The vopcop has no equivalent of the ‘detail’ mode of the attribute vop, it can only run SIMD for each pixel. I don't recommend looping over an array of pixel values to get the max or min, as that would be very slow for large images.

BabaJ
In SOPland I would get around something like this by first creating a detail attribute, from runnning in detail mode of a wrangle, and import that value to use as reference in the next wrangle.

Attribute Promote is the node you are looking for in SOP Land. I'm glad you are very enthusiastic about VEX, but it should be considered a last resort to run in detail mode, especially if there are c++ nodes that do what you are after.
User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
There's no node to get the min/max value of an image plane in cops.

There is though a min and max node to get min and max values from the input.

Looping over each pixel is actually desirable for me even with large images.

Attribute Promote is the node you are looking for in SOP Land. I'm glad you are very enthusiastic about VEX, but it should be considered a last resort to run in detail mode, especially if there are c++ nodes that do what you are after.

When I said creating a detail attribute, in detail mode - it was implied there was also some processing done in that wrangle while in detail mode as well to get the desired value of the Attribute for use in other places of the scene.

Otherwise, yes Attribute Promote is handy.

My use of VEX is not about enthusiasm…it is a last resort(detail mode), because quit often it's the only way to build the tools that I want and/or at this stage - building blocks for future tools.

Actually would be nice if we could have a wrangle that goes in ‘logic’ mode or whatever it could be called. Even detail mode has it's limitations.

A mode where multi-threading is sacrificed, basically locking the wrangle down with priority affect on the scene; It's code executed in logic/sequential form.

Actually because of all this I did in the past looked into building my own functions in C++ through the HDK - but I ran into many issues and roadblocks that couldn't be resolved;

I wasn't able to get enough information through the docs…and as a good place these forums are with people like yourself answering when you can - my questions would be far too many for a format like this.

If I had a personal tutor - someone I could pick their brains in person and clarify with - then definitely would go the C++ route(within Houdini).

But for now VEX it is.

As always your input is appreciated. - Thanks.
User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi again,
you could do this in SOPs
use “attribute from map” now the pixels are points and you know what to do.

alternatively in cops:

put image to analyse in second input and write it to an array. sort the array and use the desired index (highest or lowest) and write it to all pixels of the output.

I always get confused in COPs because of the way the pixels are sorted in rows…

Lets see if i can put the second option together now… have not done COP Filters in a while… maybe i find it in my vaults (image to array…)

Attachments:
attrib from map.PNG (588.7 KB)

User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi Babaj,
i made something for you. It is not finished but a good start.
It will find the highes r (of rgb) value in one row of the image. It needs a second loop for the v (uv). A nested loop…

If you need help finishing it let me know. But i am of to bed now.

The idea is to read an image from the second COPs input into an array. Sort the array and reverse it and you get the highest value.

As you can not store the output value (highest r) in some sort of meta data i use the whole image.

The image in the first input needs to be the same size as i read the pixel dimensions from there. But you could introduce parameters for that.



Have Fun

Olaf


edit: Maybe i should point out that the calculation of the u (uv) is not perfect as it does not hit a pixel in the center… This needs fixing. But its too late now.
Edited by Olaf Finkbeiner - May 28, 2018 17:43:39

Attachments:
cops_find_highest_r_value.hiplc (58.6 KB)
find_highest_r_value.PNG (116.9 KB)

User Avatar
Member
7771 posts
Joined: Sept. 2011
Offline
Konstantin Magnus
https://www.sidefx.com/forum/topic/31736/ [www.sidefx.com]
https://www.sidefx.com/forum/topic/50179/ [www.sidefx.com]

jlait
Dilate/erode will act as a maximum/minimum in a square region depending on sign of the operation. Ideally you could just set this to 3200 for your 3200x3200 image, but because COPs tries to compute the overscan this gets too expensive. So instead do two passes. First dilate/erode by 128. Then scale by 1/64 which will be safe - you won't miss any max/mins because each max/min already got spread everywhere in 128 tiles. Now do another dilate/erode and get a solid patch of colour for use elsewhere in COPs.

Ah, there you go. I was thinking the dilate/erode would be the closest thing to the proper way to do this. Even though you can loop over all the pixels for each pixel, doesn't mean you should.
Edited by jsmack - May 28, 2018 17:47:21
User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
Thanks very much Olaf - Konstantin and jsmack.

You all gave me much to chew on and I appreciate it.

For the first suggestion you gave Olaf, ref: bring into sops with attribute map.

I didn't want to do that because for my current inquiry I was looking for something to aid dynamically while in COPs.
Although I have forgot about being able to bring an image back into SOPland, I appreciate the reminder and will use this approach in the future when needed/becomes helpful at the time for different contexts.

I looked at Konstantines first link and the hip file from the second post of that reference makes use of the equalize node. I haven't tried that approach yet but from a cursory look at the layout seems like something I could do/understand.

The second link of Konstantine perked my interest from jlaits comment - the same one jsmack referenced. Although I don't understand it - something to explore and may be a better alternative to what I currently tried, which was:

Olaf you gave me an example with the array/uv combination. I chose to work with that at first because it looked like something I could use in different contexts.

Mainly because using the for loops in vops( help my poor skills in vops) and the accessing of pixels by position.

By looking at your example I was confused at first and couldn't figure out how the heck the r values were being accessed.

Even though I finally figured out it was through the COP Input node, it still puzzled me as to how with this node.

This was because I was assuming all the pixel locations would inherently have all the different type values accessible in the same way through this node, e.g. I didn't see any reference on the COP input node to rgb as opposed to Hue or Saturation.

So with a bit more searching I realized that although elements like hue, saturation, luminance, etc. are available in the network to work with - the basic setup is for rgb ‘only’ - so realized that it became clear of what the paramter Component was referring to - so then I got how the whole setup worked.

However, I had difficulty seting up a nested for loop. And if you would care just to illustrate an example of that it is appreciated.

Although what I did works - I made use of running over the total number of pixels ( Rh x Rw ) and with the use of div and mod nodes to index, was able to accomplish what a nested loop could do.

In the final working hip I am posting here, hopefully it illustrates what I was trying to accomplish.

With the bright node, I now can just adjust that, while my fit/ramps can stay the same relatively across a range of brightness adjustments.

And as jsmack pointed out in saying “I don't want to do that” ie. per pixal operation. He was right in that even though the current set up works it does take a fairly long time to wait when say I make a brightness adjustment.

It's actually faster I just use the inspect cursor to find my brightest pixels values and re-enter them manually in my fit parameter - or at least getting a value that still gives me the same approximate desired results of the ramp.

Thanks again all for helping me learn how to do ‘new stuff’.

Attachments:
COPS Find Highest Color Value.hiplc (110.9 KB)

User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi BabaJ,

it is a bummer but the approach of reading the image into an array is damn slow. Its all single threaded etc.
It takes about 15 sec on my machine for 512 x512… ( i will post the scene here with the nested loop too)…
BUT THIS IS NOT A GOOD IDEA as it is very slow…

If you use the attrib from map on points it takes milliseconds (also included in the scene i attached).
I tested it with a 3.2k hdr and a 3.2k grid … it takes 40 ms (loading from disc obviously not accounted for!)
TIP: do not turn on the 3d viewport… its 10million points…
I wrote the values in P and created a detail attribute maxP

You can read this with: detail(“../../../obj/attribfrommap_on_grid/attribcreate1”, “maxP”, 0)
in a COPS parameter if you want…
you could also reference the filenames etc. you would not notice that the operation is done on points while working in COPS…

It was fun trying this again…

greetings

Olaf
Edited by Olaf Finkbeiner - May 29, 2018 18:00:50

Attachments:
cops_find_highest_r_value_02.hiplc (182.0 KB)

User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
Thanks Olaf for ‘pushing’ me back in the direction of attribfrommap. I've got many more ideas for other projects from working through your example.

Definitely much faster than the pixel x pixel approach. I tested it out in my project with much higher image resolution and theirs no performance ‘hit’ that I can notice.

However, this is only good for ‘one offs’…in my current setup where I need to adjust brightness before applying the filter I have to:

> put down a rop node to export
> re-import with attributefrom map
> then switch the cops source and reload.

So this workflow gets very slow. (the netbox colored orange in the hip file).

So I looked at konstantins first link and tried the equalize node - and this works for my purpose. The main benefit I can stay in chops -

The easiest was the dilate/erode noded that jlait/jsmack mentioned.

Its only one node…however it's only good for small image sizes. Even breaking it up into a series of higher resolutions like jlait suggests, it gets very slow.

So it seems for working with larger image sizes best way to go is using the equalize and subtract nodes.

Attachments:
COPS Find Highest Color Value v1.hiplc (225.2 KB)

User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi BabaJ,
there is another much better way of doing this.
you can read images into sop directly from cops via “heightfield file” sop into a volume…
If you dont visualise in viewport it is also fast!
getting a max value is build in
and you can even use “Luminance” or each rgb channel or whatever.

And with sopimport (in cops) you can even go back to cops!)

I just recently used this extensively and completely forgot…

I just tried it witha 16k hdr and it is fast!
Also no need to write to file etc.
This was introduced with all the terrain tools.



greetings

Olaf
Edited by Olaf Finkbeiner - May 31, 2018 14:43:49

Attachments:
cops_to_sops_and_back.hiplc (92.7 KB)
heightfield_file.PNG (89.1 KB)

User Avatar
Member
2041 posts
Joined: Sept. 2015
Offline
Thanks very much for the tip Olaf.

This method is by far the best so far.

I can also remove the ‘OUT_to_cops’ node since I am directly accessing the wrangled highest red value determined in SOPs;

I added a convertheightfield node - to polygon.

With this method I basicly can now sop wrangle some post Comp operations - which in some cases is much simpler than setting up pre-shading wrangling.

So I guess if I combine this with a formula I came across ( which I haven't tried yet ) I can basically wrangle comp work based on xy screen resolution:

The formula looks like it takes care of your cameras focal length and so on, of course if using orthogonal it's not needed:

string cam = “/obj/cam1”;

vector res = chv(cam + “/res”);

float aperture = chf(cam + “/aperture”);

float focal = chf(cam + “/focal”);

vector pos = ptransform(cam,@P);

float pxwidth = length(pos)*aperture/focal/res.x;

Attachments:
COPS Find Highest Color Value via Heightfield.hiplc (98.4 KB)

User Avatar
Member
323 posts
Joined: Jan. 2015
Offline
Hi BabaJ,
you are welcome. And sure you dont need the NULLs they are cosmetic…

Have Fun

Olaf
  • Quick Links