How to work out the actual resolution of an image.  

All things panoramic.
An open forum for every topic on photography, panoramas, IT or related.
no avatar
wjh31
Member
 
Topic author
Posts: 455
Likes: 0 post
Liked in: 0 post
Joined: Thu Apr 09, 2009 11:23 pm
Location: Surrey, UK
Info

How to work out the actual resolution of an image.

by wjh31 » Wed Dec 22, 2010 6:41 pm

After yet another 'record' at 200+GP, which only has 112GP effective being put in it, i was reminded of a few comments made during the discussion of the first 0.1TP picture by rio-hk.

The comments came from Castillonis, in which he mentioned a set of slides that came from a google talk (http://www.dicklyon.com/phototech/PhotoTech_27_Resolution_Slides.pdf) which contains discussion of how a fourier transform can be used to compare how much real resolution there is in an image.

Based on this i decided to have a look at seeing if i could impliment such an analysis. Here are the results:
Code: Select all
import numpy
from PIL import Image, ImageOps

def find_nearest(array,value):
    idx=(numpy.abs(array-value)).argmin()
    return idx

img=ImageOps.grayscale(Image.open('filename.ext'))

array=numpy.asarray(img)

fft_int=numpy.abs(numpy.fft.fft2(array))
size=fft_int.shape
fft_int=fft_int[0:size[0]/2,0:size[1]/2]
size=fft_int.shape
orig=fft_int.sum()
res=numpy.zeros(50)
for i in xrange(50):
    res[i]=fft_int[0:size[0]*(i+1)/50,0:size[1]*(i+1)/50].sum()
res/=orig

numpy.savetxt('data.txt', res)

print "95% of mag:" + str(float(find_nearest(res, 0.95))/50.)

print "90% of mag:" + str(float(find_nearest(res, 0.90))/50.)

print "80% of mag:" + str(float(find_nearest(res, 0.8))/50.)

print "70% of mag:" + str(float(find_nearest(res, 0.7))/50.)

print "60% of mag:" + str(float(find_nearest(res, 0.6))/50.)

Forgive the lack of commenting or whatever code conventions may exist, this was thorwn together today just to see if it would work.

It loads an image, converts it to grayscale, then to an array. The fft is then found of this array, which also has it's magnitude taken. Over 50 steps, it then sums the magnitude of the array, and shrinks the array, to determine what magnitude remains from cutting off the high frequency part of the FT. High frequency of course corresponds to high detail, so an image whith alot of detail will loose noticable amounts of magnitude as the high frequency components are cut off. Similarly low detail images will have little high frequency detail so little will be lost. The results of these 50 steps are printed to file, then some points along it are highlighted with the sclaing.

Ive attatched two images which i tested it with. An 'original' image scaled down from a recent 100MP stitch, and a version for comparison, which was scaled down 50% (to a quarter the resolution) then back up. Results of this code are:
Code: Select all
HQ version:
95% of mag:0.88
90% of mag:0.8
80% of mag:0.7
70% of mag:0.62
60% of mag:0.52
LQ version:
95% of mag:0.58
90% of mag:0.44
80% of mag:0.36
70% of mag:0.3
60% of mag:0.26

The results of the LQ version of the image show that the image could be scaled to 0.58x its size with little loss of magnitude, and therefore imformation, whereas the HQ version would only be able to be scaled to 0.88x it's original size for a comparable loss of information.

So how does this apply with hyperresolution images? clearly this is not suitable for multigigapixel images, due to time and memory constraints. So to test 'real world' application, i took a 5000x5000px crop from the center of one of my images (http://lifeinmegapixels.com/location/elmo) and fed it to the code. It gave me these results:
Code: Select all
95% of mag:0.8
90% of mag:0.64
80% of mag:0.44
70% of mag:0.34
60% of mag:0.26

So that image could actually be scaled down to 2/3rds (0.8*0.8=0.64) of it's advertised resolution with no significant loss. And that's a high detail area of the image, it taken from e.g the sky i'd expect a much less favourable rating.

Although not implimented here, one can imaging cutting large images into appropriately sized tiles, each of which has it's 95% resolution found. The 'true' resolution of the image would then be the sum of the 95% resolution of each tile. This would account for both low quality images, aswell as boring (i.e 50% sky, out of focus foreground etc) images.

no avatar
pns
Member
 
Posts: 25
Likes: 0 post
Liked in: 0 post
Joined: Thu Jun 14, 2007 1:20 pm
Info

by pns » Thu Dec 23, 2010 12:05 am

wjh31 wrote:After yet another 'record' at 200+GP, which only has 112GP effective being put in it, i was reminded of a few comments made during the discussion of the first 0.1TP picture by rio-hk.

The comments came from Castillonis, in which he mentioned a set of slides that came from a google talk (http://www.dicklyon.com/phototech/PhotoTech_27_Resolution_Slides.pdf) which contains discussion of how a fourier transform can be used to compare how much real resolution there is in an image.

Based on this i decided to have a look at seeing if i could impliment such an analysis. Here are the results:

<snip>

thank you for this. sorry for my ignorance, but... what language is this, and how could a mere mortal try it on one's own images?
(any chance of a matlab port?)

wjh31 wrote:Although not implimented here, one can imaging cutting large images into appropriately sized tiles, each of which has it's 95% resolution found. The 'true' resolution of the image would then be the sum of the 95% resolution of each tile. This would account for both low quality images, aswell as boring (i.e 50% sky, out of focus foreground etc) images.

would that be the sum or the average?
how do you think this would work on water, say choppy ocean under wind, with lots of detail but hardly more interest than plain sky?

cheers,
pns

no avatar
wjh31
Member
 
Topic author
Posts: 455
Likes: 0 post
Liked in: 0 post
Joined: Thu Apr 09, 2009 11:23 pm
Location: Surrey, UK
Info

by wjh31 » Thu Dec 23, 2010 11:09 am

pns wrote:thank you for this. sorry for my ignorance, but... what language is this, and how could a mere mortal try it on one's own images?
(any chance of a matlab port?)

It's in python. To use it you'd need to install python (this was done with 2.5, havent tried in it other versions) aswell as the numpy and PIL modules. Then just adjust the filename near the start of the script to the image you want to use, and run it. I dont currently have matlab so wouldnt be able to port it right now, but it's not a particularly complex procedure: import image, take fft, add up some bits of it.

pns wrote:would that be the sum or the average?
how do you think this would work on water, say choppy ocean under wind, with lots of detail but hardly more interest than plain sky?

My initial thought would be the sum. Youd find the 95% resolution of a tile (as e.g 0.7) and the resolution provided by that tile would be it's pixel resolution*0.7*0.7. Repeat that for all tiles and you'd get a total.

However having though of this further, the same image might give very different results depending on the tile size you chose. Say you had an image which is half sky, half high detail ground: two vertical tiles would give one high and one low resolution tiles, however 3 vertical tiles would have two of them containting significant detail.

Your issue with the choppy ocean is a similar one to an image which is noisy, it results in higher frequency information in the image which is not actually of interest, although resolving choppy waves would technically count towards the resolution of an image if not the interest. If waves and noise came into the image at a narrow bandwidth, one could imagine trying to detect these and exclude them from the count, but that is now getting into much more complex coding/algorithms. In it's current state i think it would only be useful for images wich have been scaled beyond their native resolution, either by the user, or by stitching/uploading software. Examples of such an occation are evident in these 0.1TP images, but i know in some of my images ive used low resolution/short focal length images to square off an image, or there is a significant portion of the foreground out of focus. These add to the pixel resolution but not the true resolution, and should be picked up by this simple script, again depending on the tile size.

no avatar
pns
Member
 
Posts: 25
Likes: 0 post
Liked in: 0 post
Joined: Thu Jun 14, 2007 1:20 pm
Info

by pns » Sat Dec 25, 2010 11:08 pm

will,
thanx for your reply, which does clarify things a bit.
(there was no mention of pixel resolution in the initial description, only "the sum of the 95% resolution of each tile", which seemed wrong. weighting by pixel resolution amounts to averaging, in my book, so i guess we agree).

an important difference between noise and choppy ocean is that noise is likely to be restricted to a small range of frequencies, while the ocean might have a much wider effect. but i haven't actually tried it, so of course i could well be wrong.

on a different note, i find the results of your experiments surprising (read interesting).
if i understand it rite, the hq image results from downsampling a much larger image, while the crop is real pixels. although the fft-quality of the latter drops much faster, i would have expected a larger difference between the 2 at 95% than .88/.8.

cheers,
pns


Who is online

Users browsing this forum: No registered users and 1 guest

cron