Dark field computations

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
gemutlich

Dark field computations

Post by gemutlich »

Hello,
I would like to perform some dark field computations with my camera. I take a sequence of images with the lens cap on, all with the same exposure settings. Then I would like to compute the average image to get the dark field image. This seems easy enough with the -average option of convert. Next I would also like to compute the standard deviation of all pixels to get an idea of the thermal noise. Thus, I need to subtract the average image from all images in the sequence, square the pixel values and compute the average over all pixels.
I can't come up with a way to do this. Can someone help me with this?
Thanks in advance!
Marcus
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Dark field computations

Post by fmw42 »

gemutlich wrote:Hello,
I would like to perform some dark field computations with my camera. I take a sequence of images with the lens cap on, all with the same exposure settings. Then I would like to compute the average image to get the dark field image. This seems easy enough with the -average option of convert. Next I would also like to compute the standard deviation of all pixels to get an idea of the thermal noise. Thus, I need to subtract the average image from all images in the sequence, square the pixel values and compute the average over all pixels.
I can't come up with a way to do this. Can someone help me with this?
Thanks in advance!
Marcus
Standard Deviation can also be calculate as sqrt(variance)=sqrt(ave(x^2) - (ave(x))^2), where x is each image.

So:
1) square each image
convert image image -compose multiply -composite squaredimage

2) take average of each squared image
convert imagesquared1 imagesquared2 ... -average averagesquaredimage

3) take average of each image
convert image1 image2 ... -average averageimage

4) square the average of all the images
convert averageimage averageimage -compose multiply -composite squaredaverageimage

5) get difference between results
convert averagesquaredimage squaredaverageimage +swap -compose minus -composite varianceimage

6 take square root
convert varianceimage -evaluate pow 0.5 standarddeviationimage


I now have a script to do the above, called stdimage, at http://www.fmwconcepts.com/imagemagick/index.html
Last edited by fmw42 on 2009-03-24T16:14:37-07:00, edited 1 time in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Dark field computations

Post by anthony »

rather than multiply, you can also square, or even square root an image using -gamma, -pow, and the new operator -function polynomial (for square only)

All of these would be faster than composing two images together as they only modify the existing image in memory, where composition creates a new image and merges the pixel data of the input together before deleteing them. All that extra, and unneeded, processing can take some time (computer wise).

But then if you only do it once, I suppose it does not matter how you do it.

Also

In another discussion I gave a link to a user who was wanting to remove dark field noise from an image (was it you?).
http://dpfwiw.com/c-2000z/low-light/index.htm
I would eventually like to update the examples of digital noise removal, in IM Examples, Photo Handling
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Dark field computations

Post by fmw42 »

anthony wrote:rather than multiply, you can also square, or even square root an image using -gamma, -pow, and the new operator -function polynomial (for square only)

All of these would be faster than composing two images together as they only modify the existing image in memory, where composition creates a new image and merges the pixel data of the input together before deleteing them. All that extra, and unneeded, processing can take some time (computer wise).

Right. This was modified from an old script I had. I had forgotten about -evaluate pow 2 to square an image (and also the new -function polynomial to do the same). Good to know that those are faster than -composite.

Thanks.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Dark field computations

Post by anthony »

Also remember that -gamma and and -evaluate pow are basically the same function but with the argument inverted ( 1/x ) so -gamma 2 is square root and -gamma 0.5 is a power of 2 function. Both should be an order of magnitude faster than -compose (no image creation/deletion) but gamma should be slightly faster than -evaluate as it is a more dedicated loop, with less switching for function selection.

This will be slight and evaluate more 'obvious' is exactly what you are doing. As such I recommend -evaluate over -gamma.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
gemutlich

Re: Dark field computations

Post by gemutlich »

anthony wrote:rather than multiply, you can also square, or even square root an image using -gamma, -pow, and the new operator -function polynomial (for square only)
...
But then if you only do it once, I suppose it does not matter how you do it.
Maybe I should be a bit more specific about what I want to do. In fact, I will need to do this more than once and so a script is what I will eventually have to write.

What I want to do is characterize a camera in terms of its thermal behaviour. The dark current depends on the temperature of the sensor. It doubles each time the temperature rises by the sensor specific doubling temperature.

It is possible to take a dark field image by leaving the lens cap on and to subtract this image from all images taken at the same exposure settings and the same temperature. Unfortunately, the dark current is also noisy. Thus, the dark field image contains a predictable part and an unpredictable part (noise). This noise is what I am after.

For this reason I am taking a sequence of dark images and average them to compute the predictable part of the dark current.

Now the question: If I use -gamma, -pow or -function how are they handled internally? Are they stored as float or as 16-bit values? Can it handle negative pixel values?

How would I get the variance over an entire image? Is there a way to sum or average all pixel values and spit out this number? It seems that -fx in combination with -formt can do something like this but I am a bit confused how exactly to compute and print out this value.

What I was thinking is to first compute the average over all images. Then subtract this average image from each image (needs to handle negative pixel values) and compute the variance of each image. Since all images are the same size I can then simply compute the average over the variances.

Thanks in advance!
Marcus
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Dark field computations

Post by fmw42 »

gemutlich wrote:
anthony wrote:rather than multiply, you can also square, or even square root an image using -gamma, -pow, and the new operator -function polynomial (for square only)
...
But then if you only do it once, I suppose it does not matter how you do it.
Maybe I should be a bit more specific about what I want to do. In fact, I will need to do this more than once and so a script is what I will eventually have to write.

What I want to do is characterize a camera in terms of its thermal behaviour. The dark current depends on the temperature of the sensor. It doubles each time the temperature rises by the sensor specific doubling temperature.

It is possible to take a dark field image by leaving the lens cap on and to subtract this image from all images taken at the same exposure settings and the same temperature. Unfortunately, the dark current is also noisy. Thus, the dark field image contains a predictable part and an unpredictable part (noise). This noise is what I am after.

For this reason I am taking a sequence of dark images and average them to compute the predictable part of the dark current.

Now the question: If I use -gamma, -pow or -function how are they handled internally? Are they stored as float or as 16-bit values? Can it handle negative pixel values?

How would I get the variance over an entire image? Is there a way to sum or average all pixel values and spit out this number? It seems that -fx in combination with -formt can do something like this but I am a bit confused how exactly to compute and print out this value.

What I was thinking is to first compute the average over all images. Then subtract this average image from each image (needs to handle negative pixel values) and compute the variance of each image. Since all images are the same size I can then simply compute the average over the variances.

Thanks in advance!
Marcus
I believe that IM can handle negatives internally to any program, but cannot store them in an image unless you use HDRI configuration of IM and an appropriate file format such as MIFF, PFM, possibly TIFF. Normal IM configurations such as Q8, Q16 (default) and Q32 without HDRI will clip values at 0 and quantumrange (255, 65535, etc). Perhaps Anthony or Magick can clarify/correct this with more detail.

see
http://www.imagemagick.org/script/high- ... -range.php
http://www.imagemagick.org/Usage/basics/#hdri

Perhaps you can bias your difference relative to mid-range for storage. The later subtract the bias. Then you won't need HDRI.

The variance is just the square of the standard deviation. So once you get the std, you can square manually or using fx as in:


convert xc: -format "%[fx: $std*$std]" info:
where $std is the standard deviation stored in a variable.

To compute the std over any one image is simple:

convert image -format "%[standard-deviation]" info:

This will print to the terminal and computes the std over all channels combined and returns the value in the range 0 to quantumrange (Q8->255, Q16->65535)

If you need to compute the std per channel, you can either separate channels or use -fx

convert image -channel r -separate -format "%[standard-deviation]" info:

returns red channel std in the range 0 to quantumrange

or

convert image -format "%[fx:standard_deviation.r]" info:

returns red channel std in range 0 to 1

If you want to send the result to a variable:

std=`convert image -format "%[standard-deviation]" info: 2>&1`
echo $std

or to a file

convert image -format "%[standard-deviation]" info: 2>&1 stdfile.txt

This is all for unix. If you are on windows, some changes are needed. See
http://www.imagemagick.org/Usage/api/#windows

P.S. For any two images you can use the compare function with -metric to get various statistics. see
http://www.imagemagick.org/Usage/compare/#statistics

compare -metric XYZ image1 image2 null:

where XYZ is any one of a number of metrics, such as rmse (root mean squared error), psnr (peak signal to noise ratio), etc. You might be able to use this between your image and your averageimage and get a meaningful statistic for your analysis rather than the variance. I would suggest that rmse is probably closest to a std.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Dark field computations

Post by anthony »

While the number is a 12 bit value, expanded to a 16 bit vaule internall by IM, that value actually represents a value from 0.0 to 1.0 A square or square root of any number in that range will by the mathematics also be in that range! Their is no overflow or problems.

When you start also adding or subtracting values at which point you could get a overflow, and clipping. How IM deal with that depend on if you use plus or add and the minus or subtract composites. One clips, the other wrapps overflow values.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
gemutlich

Re: Dark field computations

Post by gemutlich »

fmw42 wrote:
gemutlich wrote: What I was thinking is to first compute the average over all images. Then subtract this average image from each image (needs to handle negative pixel values) and compute the variance of each image. Since all images are the same size I can then simply compute the average over the variances.
I believe that IM can handle negatives internally to any program, but cannot store them in an image unless you use HDRI configuration of IM and an appropriate file format such as MIFF, PFM, possibly TIFF.

P.S. For any two images you can use the compare function with -metric to get various statistics. see
http://www.imagemagick.org/Usage/compare/#statistics

compare -metric XYZ image1 image2 null:
Thank you for these hints! In fact, compare is the tool of choice since I do not explicitly have to compute the difference image. Now I just have to use convert -average to compute the average image and then compare -metric to get the individual statistics.

Thanks!
Marcus
gemutlich

Re: Dark field computations

Post by gemutlich »

anthony wrote:While the number is a 12 bit value, expanded to a 16 bit vaule internall by IM, that value actually represents a value from 0.0 to 1.0 A square or square root of any number in that range will by the mathematics also be in that range! Their is no overflow or problems.
Thank you very much for confirming this! This means that I will have no problems using compare.

Marcus
Post Reply