POV-Ray : Newsgroups : povray.general : macro to find average colors of image_map : Re: macro to find average colors of image_map Server Time
4 May 2024 03:10:32 EDT (-0400)
  Re: macro to find average colors of image_map  
From: Sven Littkowski
Date: 2 Aug 2017 22:19:01
Message: <59828815@news.povray.org>
On 02.08.2017 22:01, Kenneth wrote:
> While working on my 'city buildings' scene, I had a need to find the aver
age of
> all the colors in a digital photo image. So I wrote this macro, which use
s
> eval_pigment.
> 
> (A note: This code doesn't actually check *every* pixel in the image. Ins
tead,
> it checks lots of random positions. My own theory is that such a 'statist
ical'
> approach produces a result that is just about as good as checking each an
d every
> pixel-- and it's faster.)
> 
> -----------
> #macro AVG_COLOR(MY_PIG) // NOTE: evaluated pigment is within the image_m
ap's
> // 1X1 POV-Ray default area.
> #local CC = seed(32);
> #local LIM_C = 0;
> #local SP = 1;
> #local SUM=<.5,.5,.5>;
> #while(SP <= 100) // 100 random points in the image are evaluated
> #local LIM_C = LIM_C + 1;
> #local TEMP_EVAL = eval_pigment(MY_PIG, <rand(CC),rand(CC),0>);
> #if(
>     (TEMP_EVAL.x < .1
>     & TEMP_EVAL.y < .1
>     & TEMP_EVAL.z < .1
>     )
>     |
>     (TEMP_EVAL.x > .9
>     & TEMP_EVAL.y > .9
>     & TEMP_EVAL.z > .9
>     )
>     )
> #local SP = SP - 1; // to IGNORE the found value, and set the main coun
ter back
> by 1
> #else
> #local SUM = SUM + TEMP_EVAL;
> #end
> #local SP = SP + 1;
> #if(LIM_C > 5000)
> #local SP = 100000; // A safety limiter, to purposely end the while loo
p
> // if the main counter SP loops more than 5000 times total.
> #else
> #end
> #end
> srgb 1.0*vnormalize(<SUM.x,SUM.y,SUM.z>) // the actual VALUE of the macro
.
> //#debug concat("\n","Total while-loop iterations = ",str(LIM_C,1,0),"\
n")
> #end
> -----------
> 
> An example of how to use the macro:
> 
> #declare P =
> pigment{
> image_map{jpeg "my_photo_image.jpg" gamma 2.2 interpolate 2}
> }
> 
> pigment{AVG_COLOR(P)}
> 
> -------------------
> SOME NOTES:
> 
> Interpolate 2 may not be needed in the image_map. I think interpolation i
s
> solely a rendering-specific operation, in which case eval_pigment ignores
 it.
> 
> The #if(TEMP_EVAL...) section is optional-- to restrict the search for co
lors to
> be within two threshold values. Very dark colors (or very bright ones) do
n't
> have much *color* in them anyway-- being close to pure black or pure whit
e
> (i.e., greyish)--   and don't add much to the final color IMO, except to 
either
> darken it with muddiness, or make it lighter and more pastel. (A debatabl
e
> point, I admit.) This keeps those found colors out of the average. To use
 EVERY
> pixel color, just make the thresholds all 0.0's and 1.0's, respectively.
> 
> It's currently set up to evaluate 100 random locations in the image (SP.)
 You
> can change that higher or lower. (The #if(TEMP_EVAL...) section actually
> increases this number-- so that 100 *useful* colors are eventually found.
)
> 
> LIM_C is a 'safety' counter, to end the while loop in the extreme case of
 not
> finding ANY usuable colors in the image_map; I included it only because o
f the
> #if(TEMP_EVAL...) thresholds, which naturally increase the number of #whi
le-loop
> iterations. Excluding some evaluated colors makes the #while loop work ha
rder!
> 
> The use of vnormalize is an easy way of 'compressing' the (large!) final 
SUM
> value, into the range from 0.0 to 1.0. (Interestingly, the final componen
ts of
> SUM are somewhere between .4 and .6-- a natural result of the 'average' o
f all
> the image colors.)
> 
> You could probably stick *any* three values into the initial SUM, as it w
ill
> ultimately be 'swamped' by the additional 100 colors that are found. I us
ed
> <.5,.5,.5>  *just in case* the total search for colors (SUM) ended up as
> <0,0,0> -- which would probably never happen anyway, except when trying t
o
> evaluate a perfectly BLACK image! But I didn't want vnormalize to be give
n
> <0,0,0> as a final input, which is 'undefined' behavior. So it's not a go
od idea
> to use <0,0,0> as the initial SUM.
> 
> Thinking of other uses of this macro: It could probably be re-written to 
be a
> color-histogram tool. Or a color-pallette generator, to find *numerous* g
eneral
> colors from an image_map background for applying to a scene's objects, to
 better
> 'harmonize' all the colors.  (I'm thinking about Old Master paintings, an
d how
> well a painting's colors harmonize with each other.)
> 
> SOME EVAL_PIGMENT DETAILS...
> In the macro, the output can be either RGB or SRGB; you can choose. But i
t made
> me think about the subtleties of eval_pigment's behavior, AND of what the

> image_map's gamma should be set to, in the code.
> 
> AFAIK, eval_pigment operates on LINEAR colors (i.e., 3.7xx's RGB color sp
ace),
> not gamma-bent colors that are usually found in a typical digital photo; 
those
> are generally gamma 2.2 or srgb. So my thinking was that eval-pigment wou
ld not
> return the colors *as I see them* in the digital photo, but rather a gamm
a 1.0
> version of the colors-- which I didn't want. So I changed the macro's out
put to
> srgb.
> 
> (By the way, in the image_map's pigment block, adding either gamma 2.2 or
 srgb
> after the image_map causes no change--none that I can see, anyway. So the

> default gamma there must be 2.2 or so, which matches most photo images.  
Or,
> perhaps POV-ray automatically chooses the proper gamma value, from the im
age
> itself?)
> 
> Comments (or corrections!) welcome!
> 
> 
> 
> 
Sounds excellent!

- Being a macro, it means that the user can set the amount of random points
?

- You could also offer different methods to capture colors inside an
image: on method is your random method, and another method would be to
sample each 2nd pixel - the user can decide about the method (where he
also can decide about which other pixel to sample: each 2nd, each 3rd,
etc.).

Just suggesting.

---
Diese E-Mail wurde von AVG auf Viren geprüft.
http://www.avg.com


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.