Page 3 of 3 FirstFirst 123
Results 41 to 52 of 52

Thread: My cat Ruby

  1. #41

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by lunaticitizen View Post
    Thanks. This is the third test using synthetic images. Here is the methodology:

    1. I created a synthetic, 4K-sized uniform JPEG image with Pillow library. (image A)
    2. I introduced Gaussian noise and Poisson noise to the above image, which simulates read noise and photon shot noise, respectively . (image B)
    3. I downsampled image B to 1920x1080 pixels for viewing on an FHD monitor. (image C)
    4. I cropped image B to 960x540 pixels. (image D)
    5. I upsampled image D to 1920x1080 pixels for viewing on an FHD monitor. (image E)
    6. I measured the mean, standard deviation, and SNR of all the images above.


    I found that the SNR of the downsampled image (image C) is higher than that of the cropped-then-upsampled one (image E). The downsampled image is also cleaner when viewed on my 24-inch FHD monitor.

    Here are the downsampled and upsampled images (image C and image E, respectively):

    Image C
    My cat Ruby

    Image E
    My cat Ruby

    Here are the measurement results:

    Code:
    
    Image A
    Mean: 118.0
    StdDev: 0.0
    SNR: inf
    
    Image B
    Mean: 118.0
    StdDev: 10.87
    SNR: 20.72
    
    Image C
    Mean: 117.5
    StdDev: 4.87
    SNR: 27.65
    
    Image D
    Mean: 117.49
    StdDev: 10.88
    SNR: 20.67
    
    Image E
    Mean: 117.49
    StdDev: 9.73
    SNR: 21.64
    And finally here is the code.
    Code:
    from PIL import Image
    from numpy import asarray
    import numpy as np
    import math
    import cv2
    
    """ Add photon shot noise (poisson noise) and read noise (gaussian noise)
    to the image
    """
    def noisy(noise_typ,image):
        if noise_typ == "gauss":
            row,col,ch= image.shape
            mean = 0
            var = 0.1
            sigma = var**0.5
            gauss = np.random.normal(mean,sigma,(row,col,ch))
            gauss = gauss.reshape(row,col,ch)
            noisy = image + gauss
            return noisy
        elif noise_typ == "poisson":
            vals = len(np.unique(image))
            vals = 2 ** np.ceil(np.log2(vals))
            noisy = np.random.poisson(image * vals) / float(vals)
            return noisy
    
    """ Calculate image's mean, standard deviation, and SNR """
    def mean_std_snr(img):
        img_int = asarray(img)
        img_float32 = img_int.astype('float32')
        img_mean, img_std = img_float32.mean(), img_float32.std()
        img_snr = 20*math.log10(img_mean/img_std)
        return({'mean': img_mean, 'std': img_std, 'snr': img_snr})
    
    files = [{'name': 'mgrey3840x2160_noiseless.jpg'}, 
             {'name': 'mgrey3840x2160_poisson_gauss.jpg'},
             {'name': 'mgrey1920x1080_poisson_gauss_downsampled.jpg'}, 
             {'name': 'mgrey960x540_poisson_gauss_cropped.jpg'},
             {'name': 'mgrey1920x1080_poisson_gauss_upsampled.jpg'}]
    
    # Generate a 4K-size JPEG image
    img0 = Image.new('RGB', (3840, 2160), color = (118, 118, 118))
    img0_pix_float32 = asarray(img0).astype('float32')
    files[0].update(mean_std_snr(img0))
    img0.save(files[0]['name'], format='JPEG', quality=100)
    
    # Add photon shot noise and read noise to the generated image
    # and calculate the mean, stdev and SNR
    img1_pix_poisson = noisy('poisson', img0_pix_float32)
    img1_pix_poisson_gauss = noisy('gauss', img1_pix_poisson)
    files[1].update(mean_std_snr(img1_pix_poisson_gauss))
    img1_pix_int = img1_pix_poisson_gauss.astype('uint8')
    img1 = Image.fromarray(img1_pix_int)
    img1.save(files[1]['name'], format='JPEG', quality=100)
    
    # Downsample image to FHD-size image for viewing on monitor
    # and calculate the mean, stdev and SNR 
    img2 = img1.resize((1920, 1080), resample=Image.LANCZOS)
    files[2].update(mean_std_snr(img2))
    img2.save(files[2]['name'], format='JPEG', quality=100)
    
    # Crop the original, noise-added  image to 960x540 pixels
    img3 = img1.crop((1440, 810, 2400, 1350))
    files[3].update(mean_std_snr(img3))
    img3.save(files[3]['name'], format='JPEG', quality=100)
    
    # Upsample the cropped image to FHD-size for viewing on monitor
    # and calculate the mean, stdev and SNR
    img4 = img3.resize((1920, 1080), resample=Image.LANCZOS)
    files[4].update(mean_std_snr(img4))
    img4.save(files[4]['name'], format='JPEG', quality=100)
    
    # Print the result
    
    for file in files:
        print(f'Filename: {file["name"]}\r\n' +
              f'Mean: {str(round(file["mean"], 2))}\r\n' +
              f'StdDev: {str(round(file["std"], 2))}\r\n' +
              f'SNR: {str(round(file["snr"], 2))}\r\n\r\n')

    Thanks for the results and I applaud the use of an artificial scene. I am also impressed by your command of code!

    I believe that the difference is caused by the resampling. Most resampling algorithms apply fancy interpolation such that going up or down results in a different image even though they may look the same.

    I'll download your image C and have a look at different re-sampling algorithms.

  2. #42

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by xpatUSA View Post
    I believe that the difference is caused by the resampling. Most resampling algorithms apply fancy interpolation such that going up or down results in a different image even though they may look the same.

    I'll download your image C and have a look at different re-sampling algorithms.
    Cancel that opinion! It is not resampling that causes the noticeable difference in SNR.

    I cropped Image C to quarter size.

    I re-sampled back to full-size with Nearest Neighbor, Lanczos3 and Bicubic algorithms.

    The SNR was the same in Image C and in all three cropped-then-upsized images.

    I also re-sampled to 960px wide, same you did, but still no difference in SNR ...

    Therefore, another factor is involved in going from C to E.

    I'll keep looking ...
    Last edited by xpatUSA; 28th March 2021 at 09:43 PM.

  3. #43

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    Ted, why did you crop Image C instead of Image B?

    I did the following:

    I generated A.

    I generated B from A.

    I downsized B resulting in C.
    -> This simulates viewing a full size image on a medium whose resolution is lower than the image's itself.

    I cropped B and then upsized it resulted in E (whose size is equal to C).
    -> This simulates viewing a cropped image on the same medium as above.

    I compared the SNR of C and E, and also compared them visually on the same viewing medium.

    The SNR of C is substantially higher than that of E. Visually I also confirmed that C is cleaner than E when viewed on the same medium.



    I also re-sampled to 960px wide, same you did, but still no difference in SNR ...
    But I found it curious that you downsampled (instead of cropping) an image and yet the SNR of the resulting image is the same as the original one's.

  4. #44

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by xpatUSA View Post
    Therefore, another factor is involved in going from C to E.

    I'll keep looking ...
    I did yet another test.

    In the GIMP, I made a 1920x1080px gray image and added some noise. Exported as noise.png.
    In Faststone Viewer, cropped middle to 960x540px, then up-sized back to 1920x1080px with bicubic algorithm. I saved it as noise-crop-up-bic.png and imported it back into the GIMP.

    GIMP mean and sd to SNR:
    noise.png: 0.526, 0.046 --> SNR 21.16dB
    noise-crop-up-bic.png: 0.525, 0.042 --> SNR 21.94dB

    It seems that different methods give slightly different results but, in the end, my results are showing that upsizing a crop from an image where the cropped area has the same content as the whole image does not significantly affect the SNR.

    Which, in turn, means that the long-forgotten cat could have been shot(!) from farther back without significant SNR effects.

  5. #45

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by lunaticitizen View Post
    Ted, why did you crop Image C instead of Image B?

    I did the following:

    I generated A.

    I generated B from A.

    I downsized B resulting in C.
    -> This simulates viewing a full size image on a medium whose resolution is lower than the image's itself.

    I cropped B and then upsized it resulted in E (whose size is equal to C).
    -> This simulates viewing a cropped image on the same medium as above.

    I compared the SNR of C and E, and also compared them visually on the same viewing medium.

    The SNR of C is substantially higher than that of E. Visually I also confirmed that C is cleaner than E when viewed on the same medium.
    But I found it curious that you downsampled (instead of cropping) an image and yet the SNR of the resulting image is the same as the original one's.
    I give up, Leo. We keep doing these tests different ways instead of the same ways to the same image images.

    I had not read this post before my post above. We will get nowhere going back and forth like this, so I fold.

    No disrespect intended, it is quite clear that you know what you are doing without further "help" from me ...

  6. #46

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    I recalculated the SNR using both Photoshop and GIMP. Here are the results.

    My cat Ruby

    With both Photoshop and GIMP, the SNR of Image C is substantially higher than that of Image E.

    With Photoshop, the SNR of Image B is similar to that of Image C.

    With GIMP, the SNR of Image B is lower than that of Image C, and similar to that of Image E.

    Btw, I couldn't configure GIMP's histogram so that it would show absolute values. I had to manually multiply the values displayed with (2^8 - 1) to get the absolute values displayed on the screenshot above. Tell me if I did something wrong.
    Last edited by lunaticitizen; 29th March 2021 at 12:37 AM.

  7. #47

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    Quote Originally Posted by xpatUSA View Post
    I give up, Leo. We keep doing these tests different ways instead of the same ways to the same image images.

    I had not read this post before my post above. We will get nowhere going back and forth like this, so I fold.

    No disrespect intended, it is quite clear that you know what you are doing without further "help" from me ...
    OK Ted, I'll review our posts later to understand where we diverged.

    Thanks for your help.

  8. #48

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by lunaticitizen View Post
    Btw, I couldn't configure GIMP's histogram so that it would show absolute values. I had to manually multiply the values displayed with (2^8 - 1) to get the absolute values displayed on the screenshot above. Tell me if I did something wrong.
    No, nothing wrong with that, Leo. Later versions, 2.9 and up, can open 16-bit images as well as 8-bit images, so the histogram levels are displayed as fractions just as you have found already. It is odd that the boxes for setting measurement range are still 0-255 though. Perhaps those numbers represent histogram bins ...

  9. #49

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    Now I (almost) understand what you meant.

    With my synthetic images, going from B -> D -> E didn't seem to change the SNR substantially.

    It implies that if I had specified a viewing medium whose resolution is the same as B, then the three images above would look the same.

    I modified my code to generate a new image, Image F which is Image B cropped to 960 pixels wide then upsampled back to the same resolution of that of Image B.

    Here is Image F.
    https://LeoCDNendpoint01.azureedge.n...nupsampled.jpg

    And here are the measurement results.
    My cat Ruby

    So Pillow and GIMP agree with Ted's original hypothesis.

  10. #50

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    Quote Originally Posted by xpatUSA View Post
    No, nothing wrong with that, Leo. Later versions, 2.9 and up, can open 16-bit images as well as 8-bit images, so the histogram levels are displayed as fractions just as you have found already. It is odd that the boxes for setting measurement range are still 0-255 though. Perhaps those numbers represent histogram bins ...
    Understood, Ted. Thanks.

  11. #51

    Join Date
    Oct 2015
    Location
    Land of the Rising Sun
    Posts
    372
    Real Name
    Leo Bhaskara

    Re: My cat Ruby

    Here is a composite of Image B and Image F cropped at 400 pixels wide. Their SNRs are similar but I think Image B is 'cleaner' or 'less coarse'. What do you think?

    My cat Ruby

    So what is the measure for image 'cleanness'?

    I ordered this book last week and it's coming soon; I hope I can find some hints inside

  12. #52

    Join Date
    Feb 2012
    Location
    Texas
    Posts
    6,956
    Real Name
    Ted

    Re: My cat Ruby

    Quote Originally Posted by lunaticitizen View Post
    Here is a composite of Image B and Image F cropped at 400 pixels wide. Their SNRs are similar but I think Image B is 'cleaner' or 'less coarse'. What do you think?
    Indeed, the spatial frequency or "grain size" does affect one's perception of noise. Early Sigma cameras were pretty bad in that respect with quite large blotching.

    My cat Ruby

    So what is the measure for image 'cleanness'?
    Yes, I asked about that earlier too. In answer to that and the equally vague word 'quality', I usually refer folks to:

    https://www.imatest.com/solutions/cpiq/

    It is a camera phone standard but I know of none such for "real" cameras.

    I ordered this book last week and it's coming soon; I hope I can find some hints inside
    Quite a book!

    I also did another test, this time with a camera (Sigma SD9) and my wall chart. About 1m and 2m shooting distances. The chart has a gray area which I selected equally in the GIMP for three shots (I upsized the crop with Bicubic then the crop again with Nearest Neighbor.

    My cat Ruby

    Result (GIMP mean and sd):

    Near: 0.381 0.014 --> 28.7dB
    Far Bicubic: 0.377 0.016 --> 27.444dB
    Far Nearest: 0.379 0.016 --> 27.490dB

    I conclude that the type of resampling has little effect for a real image but the act of resampling does. There is also the possibility of different focus and hand movement between the near and far shots. Subject framing in the far shot was about half that of the near.

    It still seems to me that the SNR of a particular subject in a frame, be that subject far or near, does not change significantly.

    This has been quite a sub-discussion so far and I've learned quite a lot just by messing around.
    Last edited by xpatUSA; 29th March 2021 at 08:47 PM.

Page 3 of 3 FirstFirst 123

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •