bugGNU Octave - Bugs: bug #67016, std produces incorrect results for...

 
 

bug #67016: std produces incorrect results for unsigned ints

Submitter:  Marek <zzmaro>
Submitted:  Fri 11 Apr 2025 12:37:04 PM UTC
   
 
Category:  Octave Function Severity:  4 - Important
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Marek Open/Closed:  * Closed
Release:  * 9.4.0 Release: 
Operating System:  * Any Fixed Release:  10.2.0 (current stable)
Planned Release:  10.2.0 (current stable)
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 16 Apr 2025 05:29:53 PM UTC, comment #15: 

opened bug #67031 to track image package std2 changes. closing report.

Nicholas Jankowski <nrjank>
Group Member
Wed 16 Apr 2025 05:24:05 PM UTC, comment #14: 

With this fix, std2 from image package is not working.
I will make the changes (as in comment #12) and prepare a minor release for image package.

Avinoam Kalma <avinoam>
Group Member
Wed 16 Apr 2025 03:58:16 PM UTC, comment #13: 

I verified the fix.  Definitely correct to put this on stable as the results have been potentially misleading for years.  Since Matlab agrees, inputs should be floating point, I think the changes for core Octave are complete.

I'm okay to close this report, but maybe it can be left open to track any necessary changes in image package.  If so, it should be re-titled to remaining issue.

Rik <rik5>
Group administrator
Wed 16 Apr 2025 01:14:49 PM UTC, comment #12: 

was about to back out that change, as i only ran the core octave tests and was concerned that the nightly builds with the image pkg would fail, but the image tests just passed as it seems std2 has no tests. doesn't seem to break statistics either. haven't tested other packages.  it will still break std2 in the nightly build for anyone using it . if that is a concern, can back it out pending any changes to the image pkg


Nicholas Jankowski <nrjank>
Group Member
Wed 16 Apr 2025 10:26:49 AM UTC, comment #11: 

i pushed a change to stable that issues an error for non-float inputs to var (and through that std) as
https://hg.savannah.gnu.org/hgweb/octave/rev/bb7c11cea4c6

that fix to std2 should avoid these errors for most images and som e bigger int values, and should never go negative. mean does return double and has some internal handling paths to reduce errors for larger int types.  if you wanted to be able to handle big int images you might have to do something other than an immediate double conversion for I though.


Nicholas Jankowski <nrjank>
Group Member
Sat 12 Apr 2025 12:00:25 PM UTC, comment #10: 

What about changing the computation in std2 to:

  J = double(I) - mean2(I);
  s = sqrt(mean(J .* J));

Here we square the values after subtracting the mean, which could be much smaller.

Avinoam Kalma <avinoam>
Group Member
Fri 11 Apr 2025 07:42:41 PM UTC, comment #9: 

@zzmaro - no worries, just wasn't sure until checking if it was a simple mis-comparison.  this was a good catch.

@jwe - yes, the simplest case is for us to also reject ints and let the image toolbox make the double conversion and issue a warning if they ever think they'll deal with high bit depth ints.  anything up to 16bit should be fine with a double conversion. i think 32bit too, but values are squared, so I'd have to check the intmax and flintmax values to see where rounding or overflow error would creep in. 

there are 32 and 64 bit uint image formats out there. generally specialized stuff (apparently some python/numpy libraries can handle them, and astronomical data folks have some formats that use it.)

but until someone hits the package up for that capability, I'd say they just convert and pass to std, and later come up with an alternate codepath for big uints if it's needed. we could even consider that path for core std if it was important enough.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 06:02:41 PM UTC, comment #8: 

comment #1:

> haven't looked through yet, but just want to be sure you're using the same images in all programs, as you mention the Lena image but linked the Barbara image.


Just for clarification - of course link is bad, it should be to Lena, as I used Lena, but as you pointed out later, it doesn't really matter - results are consistent for other images, like Barbara.
I'm sorry for that.

Marek <zzmaro>
Fri 11 Apr 2025 05:03:32 PM UTC, comment #7: 

Is the result of var computed using integers?  That seems bad.  Maybe it would be best to disallow integers for var and std.  Then std2 can convert its argument to double for the computation and return a double value unless the input is single, in which case it would return a single value.

I believe the only place where conversion to double could lose precision is for 64-bit ints.  For those, we could warn if the absolute value of any of the input values are larger than flintmax.  If I understand correctly, image data does not use 64-bit integers, so that should not cause trouble for calculations on images.

Am I missing something?

John W. Eaton <jwe>
Group administrator
Fri 11 Apr 2025 04:18:21 PM UTC, comment #6: 

alternatively, may be able to just change the order of operations to avoid going negative. might wind up with intmax limits, but will give it a look.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 04:11:42 PM UTC, comment #5: 

option 2 would just be to have std do a type check and throw an error on non-floating point inputs, and have std2 do the image data conversion to double before passing to std.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 04:09:58 PM UTC, comment #4: 

ok.  image data is an unsigned int.  when computing the variance, that clips negative values to floor.  so any values below the mean get clipped to an element variance of 0. when I artificially force the values to do this in e.g., excel, you get std of 50.33 instead of 72.0

maybe this is why matlab errors if std is given a non-floating point value. i guess their std2 does something special.

since our std2 needs to operate on image data, and appears to just be a wrapper to std, i'll take a look at fixing this (can probably just do a conversion to double, maybe with a potential warning about accuracy for large int types, that should stay silent for most int-based images?)

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 03:41:33 PM UTC, comment #3: 

ok, took a few minutes and compared the imread outputs from both programs and passed them to each other.  the image data is identical, and std in each program is consistent for either set of data, but consistently different between programs.  so this semes to be an issue with std not the image toolbox.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 03:25:53 PM UTC, comment #2: 

confirming the same thing occurs using Barbara (so i assume from your values you did actually use Lena)

matlab 2024b:


[bGray, map] = imread('barbara_gray.bmp');

bGray_signal_mean = mean(bGray(:))

bGray_signal_mean =

  126.5860

>> bGray_signal_mean2 = mean2(bGray(:))

bGray_signal_mean2 =

  126.5860

 >> bGray_signal_noise = std(double(bGray(:)))

bGray_signal_noise =

   72.0555

>> bGray_signal_noise2 = std2(bGray(:))

bGray_signal_noise2 =

   72.0554


Octave 10.1.1:


>> [bGray, map] = imread('barbara_gray.bmp');

>> bGray_signal_mean = mean(bGray(:))
bGray_signal_mean = 126.5860366821289

>> bGray_signal_mean2 = mean2(bGray(:))
bGray_signal_mean2 = 126.5860366821289

>> bGray_noise = std(bGray(:))
bGray_noise = 50.07557941940107

>> bGray_noise2 = std2(bGray(:))
bGray_noise2 = 50.07557941940107


noting that mean2(img) and std2(img) are just mean(img(:)) and std(img), the question is why are we computing std of a vector differently than matlab.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 03:06:16 PM UTC, comment #1: 

haven't looked through yet, but just want to be sure you're using the same images in all programs, as you mention the Lena image but linked the Barbara image.

Nicholas Jankowski <nrjank>
Group Member
Fri 11 Apr 2025 12:37:04 PM UTC, original submission:  

Hello,

I would like to report a potential bug in STD calculation method for STD/STD2 functions from Image processing package.
Octave version 9.2.0/9.4.0
Image package version: 2.14.0

Image STD calculation differs between Octave and Matlab/Excel/ImageJ calculation.

Image used for calculation was Lena gray, 8bit, 512x512px - https://eeweb.engineering.nyu.edu/~yao/EL5123/image/barbara_gray.bmp

Code used in Octave/Matlab:

clc;

% pkg load image  % Only for Octave
[lenaGray, map] = imread('lena_gray.bmp');
lenaGray_signal_mean = mean(lenaGray(:))
lenaGray_signal_mean2 = mean2(lenaGray(:))
% lenaGray_noise = std(lenaGray(:))    % Only for Octave
lenaGray_noise2 = std2(lenaGray(:))


Results:

Octave:
lenaGray_signal_mean = 125.16
lenaGray_signal_mean2 = 125.16
lenaGray_noise = 31.568
lenaGray_noise2 = 31.568

Matlab:
lenaGray_signal_mean = 125.1615
lenaGray_signal_mean2 = 125.1615
lenaGray_noise2 = 45.2043

Mean values are exactly the same, but STD differs. Excel calculation and ImageJ check give similar results to Matlab:

Excel:        
Mean: 125.1614609
std.p: 45.20427708
std.s: 45.2043633

ImageJ (ver. 1.54k)
Mean: 125.1
Std:    45.204

Marek <zzmaro>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by avinoam (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by zzmaro (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-04-16 nrjank Open/ClosedOpen Closed
    2025-04-16 rik5 CategoryOctave Package Octave Function
        StatusConfirmed Fixed
        Fixed ReleaseNone 10.2.0 (current stable)
        Planned ReleaseNone 10.2.0 (current stable)
    2025-04-11 nrjank Severity3 - Normal 4 - Important
        Summarystd function produces different values than matlab on same image data std produces incorrect results for unsigned ints
    2025-04-11 nrjank SummaryImage STD function in Image processing toolbox returns incorrect value std function produces different values than matlab on same image data
    2025-04-11 nrjank StatusNone Confirmed
        Operating SystemMicrosoft Windows Any

    Back to the top

    Powered by Savane 3.14-962f.
    Corresponding source code