bugGNU Octave - Bugs: bug #65384, image clim and climmode properties...

 
 

bug #65384: image clim and climmode properties improperly set for RGB and integer cdata

Submitter:  Nicholas Jankowski <nrjank>
Submitted:  Wed 28 Feb 2024 10:54:58 PM UTC
   
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  10.1.0 (current default) Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 02 Mar 2024 10:48:14 PM UTC, comment #8: 

I pushed a change to stop setting the 'clim' property in image.m.  See https://hg.savannah.gnu.org/hgweb/octave/rev/2edd93f097ff.  This seems to fix the problem mentioned in this bug report.
 
I'll open a new bug report for the issue that 'clim' is updated when the data itself is of TrueColor.

Rik <rik5>
Group administrator
Fri 01 Mar 2024 08:11:10 PM UTC, comment #7: 

ok thanks, that agrees my understanding.  removing the block seems to be the right thing to do for this immediate problem.  for the second issue, i glanced briefly at the __go_image__ code but didn't follow to see where it was deciding to change clim after setting an RGB cdata.

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Mar 2024 07:25:27 PM UTC, comment #6: 


> ok, out at m-code level, yes that whole block seems unnecessary.  but i don't think the caxis('auto') is needed.


Sorry, I didn't make myself clearer.  The 'caxis' command was merely to show what Octave was getting wrong, and how to recover Matlab behavior.  The root cause is that setting 'clim' property to any value changes the mode to 'manual'.  I think we fix that by simply removing the block of code in image which is unnecessarily setting the 'clim' property.

Separately, Matlab says "The clim function only affects graphics objects that have the CDataMapping property set to "scaled". It does not affect graphics objects that use truecolor or have the CDataMapping set to "direct"."

So, TrueColor (RGB) should not be changing "clim" nor using it to affect display.

Rik <rik5>
Group administrator
Fri 01 Mar 2024 05:07:38 AM UTC, comment #5: 

confirmed that doesn't cause any test suite errors.  I'll work up a patch against default with some BISTs including an xfail for that

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Mar 2024 04:45:19 AM UTC, comment #4: 

ok, out at m-code level, yes that whole block seems unnecessary.  but i don't think the caxis('auto') is needed.

set('clim') both changes the clim values to [intmin intmax], and setting it also sets the 'climmode' to manual.  Removing it keeps the 'auto' setting so that  clim is adjusted after the subsequent set command no matter whether cdata was type int.  I'm not sure if maybe that block was put there because of former matlab behavior or not, but it can't find any case where it's necessary for compatibility now.  running a make check on that now, but of course we don't exactly have a large test suite for the graphics functions. (e.g., i see imagesc doesn't have any)

i do notice something else though after fixing that.  clim should apparently only be adjusted when using a 2d cdata.  for a 3d cdata matlab leaves clim alone. that change appears to be done by __go_image_ though, so i haven't been able to step through to see where exactly it happens.

the main issue only occurred when the image was created as RGB and with an integer. below are some test results for both before and after the fix and compared with matlab. I'll work up some BISTs.

Matlab 2023b, same output whether uint8 or not, makes colored blocks:

close all; clear;
hf = figure;hax = gca;
get(hax, 'clim'), get(hax,'climmode')
ans =  0     1

ans = 'auto'

him = imagesc(uint8(randi([1 64], 16, 16, 3)));
get(hax, 'clim'), get(hax,'climmode'),get(him, 'cdatamapping')

ans =   0     1

ans = 'auto'

ans = 'scaled'

set(him, 'cdata', rand(16,16))
get(hax, 'clim'), get(hax,'climmode'),get(him, 'cdatamapping')

ans = 0.0046    0.9961

ans = 'auto'

ans = 'scaled'



Octave 9.0.90, with double input, makes colored blocks:

close all; clear;
hf = figure;hax = gca;
get(hax, 'clim'), get(hax,'climmode')
ans =

   0   1

ans = auto
him = imagesc(randi([1 64], 16, 16, 3));
get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

    1   64

ans = auto
ans =

     1    64     1  -Inf

ans = scaled
set(him, 'cdata', rand(16,16))
get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

   4.8908e-03   9.9539e-01

ans = auto
ans =

   4.8908e-03   9.9539e-01   4.8908e-03         -Inf

ans = scaled


Octave 9.0.90, with uint8 input, before fix, makes solid purple block:

close all; clear;
hf = figure;hax = gca;
get(hax, 'clim'), get(hax,'climmode')
ans =

   0   1

ans = auto
him = imagesc(uint8(randi([1 64], 16, 16, 3)));
get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

     0   255

ans = manual
ans =

     1    64     1  -Inf

ans = scaled
set(him, 'cdata', rand(16,16))
get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

     0   255

ans = manual
ans =

   2.6834e-03   9.9864e-01   2.6834e-03         -Inf

ans = scaled


Octave 9.0.90, with uint8 input, after fix, makes colored blocks:

>> close all; clear;
>> hf = figure;hax = gca;
>> get(hax, 'clim'), get(hax,'climmode')
ans =

   0   1

ans = auto
>> him = imagesc(uint8(randi([1 64], 4, 4, 3)));
>> get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

    3   64

ans = auto
ans =

     3    64     3  -Inf

ans = scaled
>> set(him, 'cdata', rand(16,16))
>> get(hax, 'clim'), get(hax,'climmode'), get(him, 'clim'), get(him, 'cdatamapping')
ans =

   9.1291e-04   9.9972e-01

ans = auto
ans =

   9.1291e-04   9.9972e-01   9.1291e-04         -Inf

ans = scaled


Nicholas Jankowski <nrjank>
Group Member
Thu 29 Feb 2024 06:02:25 AM UTC, comment #3: 

Actually, it might be as simple as deleting that bit of code.  I did a few quick tests and the results look the same as Matlab.  More testing would be needed.

Rik <rik5>
Group administrator
Thu 29 Feb 2024 05:55:20 AM UTC, comment #2: 

You can reproduce the Matlab output by running the commands as before and then adding one more


caxis ('auto');


If you check 'clim' and 'climmode' immediately after the call to imagesc you will find that they are [0, 255] and 'manual' respectively.  When you change the data to be of type double, the 'clim' value does not update because it is set to 'manual'.

See image.m and this block


  if (do_new && ! ishold (hax))
    ## Set axis properties for new images
    ## NOTE: Do this before calling __go_image__ so that image is not drawn
    ##       once with default auto-scale axis limits and then a second time
    ##       with tight axis limits.
    if (! isempty (img))
      if (isempty (get (hax, "children")))
        axis (hax, "tight");
      endif

      if (ndims (img) == 3)
        if (isinteger (img))
          mn = intmin (img);
          mx = intmax (img);
          set (hax, "clim", double ([mn, mx]));
        endif
      endif

    endif  # ! isempty (img)


Maybe we need to recode the bit starting with "isinteger"

Rik <rik5>
Group administrator
Thu 29 Feb 2024 02:43:40 AM UTC, comment #1: 

playing around a bit - matlab and octave behave the same if you use image instead of imagesc.  There, 'cdatamapping' is set to manual.  if you change cdata the image changes to a dark purple. if you then set cdatamapping to scaled, it looks like the colored squares.  in octave, if you had first set the image cdata to type uint8, changing cdatamapping to scaled and assigning the cdata fails to change the image to colored squares. my guess is that something internal is being set to type uint8, and the set is failing to update that type so the scaling never changes.

Also, 'clim' is strange.  clim is supposed to be a 2-element vector indexing the colormap, and only belongs to the axes object. In matlab, get(imagehandle, 'clim') produces an error.  But in octave, while get(imagehandle) shows no clim property:


H = image;
get(H, 'clim')
ans =
     1    62    1   -Inf
get(gca, 'clim')
ans
     0   1



H = image (zeros (16, 16, 3, 'uint8'));
get(H,'clim')
ans =

     0     0   Inf  -Inf

get(gca,'clim')
ans =

     0   255


class of both is still double, but there are apparently some internal hidden properties in image, and seems like creating a uint8 image is setting one in a way that prevents it from being properly updated.  Will try to step through image to see if i can see what it is.

Nicholas Jankowski <nrjank>
Group Member
Wed 28 Feb 2024 10:54:58 PM UTC, original submission:  

following on the conversation in bug #56175, matlab 2023b and octave behave differently when an image object's CData property has it's class type changed. E.g:



figure
H = imagesc (zeros (16, 16, 3));
set (H, 'CData', rand (16));


both programs first produces a black image, then the set command creates an image with randomly colored squares. After both the imagesc and set commands class(get(H, "CData")) returns 'double'.


figure
H = imagesc (zeros (16, 16, 3, 'uint8'));
set (H, 'CData', rand (16));


In this example, both again produce a black image.  Then with the set command Matlab produces the randomly colored squares. class(get(H, "CData")) returns uint8 after the imagesc and double after the set. 

Octave produces the same black image, but then after the set command it changes to a solid dark purple. class(get(H, "CData") returns 'uint8' and 'double' before and after the set as expected, and the CData is the same 0's and random [0,1] values as matlab.  Both programs have cdatamapping set to 'scaled'.

Nicholas Jankowski <nrjank>
Group Member

 

(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 nrjank (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 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2024-03-02 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 10.1.0 (current default)
    2024-03-01 nrjank Summaryimage 'cdata' property fails to update class-dependent color behavior image clim and climmode properties improperly set for RGB and integer cdata

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code