Image sequence per-pixel percentile function?

Discuss digital image processing techniques and algorithms. We encourage its application to ImageMagick but you can discuss any software solutions here.
Post Reply
bpoo
Posts: 2
Joined: 2017-06-30T00:05:48-07:00
Authentication code: 1151

Image sequence per-pixel percentile function?

Post by bpoo »

Hi all,

I'd like to know if there is a script or set of commands I could run to output the equivalent of the following

convert -evaluate-sequence percentile=<1..99>

(percentile of course isn't a valid function, just using it here as descriptive for the desired processing). That is, to process a sequence of images where the output is an image where each pixel is the nth percentile value across the same pixel location across all images. e.g. percentile=50 would produce the same output as median

I find some interesting results from adding or subtracting max, min, median outputs to produce new derived images. Being able to specify percentile would add more flexibility and combinations. It may be a time consuming algorithm since it would in the most direct implementation require sorting pixel values for each location across all images.

Wanted to check if anyone has written a script for this already or has some suggestions for how to best implement it.

Thanks!
bpoo
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Image sequence per-pixel percentile function?

Post by snibgo »

So if you put "25", the result image would have the pixel at each (i,j) set equal to the pixel of the image that was a quarter way down the list of lightnesses at location (i,j). Is that right? If we had 20 input images, this would be the 5th lightest pixel.

IM doesn't have operations to sort pixels, so I wrote one (as a process module). With this, a script could be written for your function.

1. Count the images (N), and calculate M where M=5 in my example.

2. For each image, size WxH, crop into columns and append these vertically, so now each is W*H high and 1 wide.

3. Append these N images sideways, so now we have one image W*H high and N wide.

4. Sort each row, in decreasing order of lightness. My process module "sortpixels" does that.

5. Crop the image, taking just the column M. Now the result is again W*H high and 1 wide.

6. Crop this into W pieces, each 1xH pixels, and append them horizontally, so the result is WxH pixels.

7. Job done.

Note: It isn't necessary that M is an integer. If it isn't, step 5 could be an interpolation.

So, a script (with just one single command?) could be written, using sortpixels. Or the entire function could be written as a process module, but with no obvious advantage.
snibgo's IM pages: im.snibgo.com
bpoo
Posts: 2
Joined: 2017-06-30T00:05:48-07:00
Authentication code: 1151

Re: Image sequence per-pixel percentile function?

Post by bpoo »

Thanks snibgo,

Yes, as you described, that's the functionality I'm looking for. I will give it a try using the steps you outline using sortpixels. And if test results look good will contribute the wrapper code back here. Incidentally the application for this is to combine multiple images of a fixed object taken from a fixed camera viewpoint with changes in physical lighting configuration (different intensities, incident angles, spot size, etc.). Since each pixel is comprised of the value from an actual image, it's possible to get good structural detail of the object without introducing artificial enhancement-specific artifacts that might result from other methods (HDR, etc.).

Thanks again for taking the time to reply in such detail. I appreciate it.
bpoo
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Image sequence per-pixel percentile function?

Post by snibgo »

For completeness, this is how a process module (or independent program) could do the job:

1. Count the images (N), and calculate M where M=5 in my example.

2. Allocate a WxH output image, and either a memory pixel array or a temporary image for Nx1 pixels.

3. For all y and x:

4. - For all N input images: populate pixel element from input(x,y).

5. - Sort the Nx1 pixel array.

6. - Copy the M'th pixel from the pixel array into the output image at (x,y).

7. End for.

8. Job done.

This would be faster than my outline above because images don't need to be cropped and appended, and would use less memory.
snibgo's IM pages: im.snibgo.com
Post Reply