Usage of fx:intensity or similar technique

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
manoweb

Usage of fx:intensity or similar technique

Post by manoweb »

Hi, I am using an expression like:

Code: Select all

"%[fx:intensity]"
to calculate an "average" number for a picture.
In short, if this number is below a certain threshold, I will increase the shutter time of the camera; if is it too high, I will reduce it.

Anyway, with this image:
http://www.manoweb.com/alesan/temp/D-20 ... 095650.jpg
I get this value:

Code: Select all

convert D-20080425-095650.jpg -format "%[fx:intensity]" info:-
0.0344
Why is it so low? :? The image is quite bright in average after all. This misleding result turns my system in a 15s exposure time that delivers a completely white image, of course.

Should I use another expression other that fx:intensity, or am I doing something basically wrong? :(

Thank you for any suggestion
bye
Alessio
manoweb

Re: Usage of fx:intensity or similar technique

Post by manoweb »

I have found that "mean" is actually a better substitute for fx:intensity but:
1) it takes MUCH longer to be processed
2) it has to be converted depending on the quantization level


1) I am working on a tiny Linksys NSLU2, 266MHz ARM processor with 32MB of RAM - Debian installed on USB hard disk:

Code: Select all

nslu2:# file=test.jpg ; time convert -size "640x480" "$file" -write "work/$file" -format "%[fx:intensity]" info:-
1

real    0m2.994s
user    0m2.540s
sys     0m0.430s

nslu2:# file=test.jpg ; time convert -size "640x480" "$file" -write "work/$file" -format "%[mean]" info:-
254.907

real    0m45.760s
user    0m3.370s
sys     0m41.930s
the difference in the time of execution is not acceptable, so I have split the resize operation and the "mean" calculation in two steps:

Code: Select all

nslu2:# file=test.jpg ; time convert -size "640x480" "$file" "work/$file"

real    0m2.804s
user    0m2.450s
sys     0m0.320s
nslu2:# file=test.jpg ; time convert -size "1x1" "work/$file" -format "%[mean]" info:-
255

real    0m0.928s
user    0m0.200s
sys     0m0.710s
2) as I use 8-bit quantization I have to take the result of the mean and divide it by 255; I am not sure how to create an expression on the "-format" option. so for now I do the math with bc invoked from a shell script:

Code: Select all

nslu2:# q=255 ; file=test.jpg ; temp=$(convert -size "1x1" "work/$file" -format "%[mean]" info:-) ; mean=$(echo "scale=3; $temp/$q" | bc) ; echo $mean
1.000
Is it possible to achieve this number directly from imagemagick?

Bye, Thank you
Alessio
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Usage of fx:intensity or similar technique

Post by fmw42 »

%[fx:intensity] like all -fx operations will report values in the range of 0 to 1 not 0 to quantum-max, so you need to scale your values.

Try

convert image -format "%[fx:int(255*intensity)]" info:

but I am not sure that is the same as the mean.

mean=`convert image -format "%[mean]" info:`
convert xc: -format "%[fx:255*$mean/65535]" info:


or
echo "scale=0; $(convert image -format "%[mean]" info:) * 255/65535" | bc
or
convert xc: -format "%[fx:int($(convert image -format "%[mean]" info:)*255/65535)]" info:
(anyone know of a cleaner shorter way to do this with only fx)

(I am on a 16-bit system, so I need to scale $mean by 255/quantum-max. On a 8-bit system, I don't think you would not need the second step)

For example if I use a standard image (logo: or rose:), I get

time convert logo: -format "%[fx:int(255*intensity)]" info:
255

real 0m0.568s
user 0m0.100s
sys 0m0.042s

time mean=`convert logo: -format "%[mean]" info:`; convert xc: -format "%[fx:int(255*$mean/65535)]" info:

real 0m0.196s
user 0m0.118s
sys 0m0.041s
230


time convert rose: -format "%[fx:int(255*intensity)]" info:
47

real 0m0.496s
user 0m0.022s
sys 0m0.024s

time mean=`convert rose: -format "%[mean]" info:`; convert xc: -format "%[fx:int(255*$mean/65535)]" info:

real 0m0.069s
user 0m0.022s
sys 0m0.024s
105

and the times are better for the second method.


With your image I get:

time convert D-20080425-095650.jpg -format "%[fx:int(255*intensity)]" info:
9

real 0m1.599s
user 0m0.966s
sys 0m0.171s

time mean=`convert D-20080425-095650.jpg -format "%[mean]" info:`; convert xc: -format "%[fx:int(255*$mean/65535)]" info:

real 0m1.378s
user 0m1.158s
sys 0m0.169s
100


See:
viewtopic.php?f=3&t=10984

for a discussion of how the r,g,b channels are combined with intensity.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Usage of fx:intensity or similar technique

Post by magick »

Fx includes the constant QuantumRange. Use it to scale Fx values to the quantum-depth of the ImageMagick release.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Usage of fx:intensity or similar technique

Post by fmw42 »

I only see the quantum depth which reports:

convert xc: -format "%q" info:
16

not 65535 or 255. Is there another string format that reports this latter?

However, my questions was really about how to do any calculation on the mean value (%[mean]) in one single compact fx statement, such as to compute 255*mean/65535.

Similarly is there a way to force %[mean] to report an 8-bit result on a 16-bit system.

I tried

convert image -depth 8 -format "%[mean]" info:

but still got a 16-bit result.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Usage of fx:intensity or similar technique

Post by anthony »

Try MaxRGB instead!

As for the actual problem why not scale the image to a single pixel and gets its intensity!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply