bugGNU Octave - Bugs: bug #36594, imshow error after changing...

 
 

bug #36594: imshow error after changing colormap

Submitter:  Fu Juay Chang <richerard>
Submitted:  Tue 05 Jun 2012 01:48:43 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:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 26 Feb 2014 04:34:13 PM UTC, comment #10: 

I applied the patch to the stable branch here (http://hg.savannah.gnu.org/hgweb/octave/rev/bf0d2e51c8f0).  It is fine without a test.

Rik <rik5>
Group administrator
Tue 25 Feb 2014 11:16:24 PM UTC, comment #9: 

The patch is attached. I modified axis to use "__image_pixel_size__" and extend image data.

In image "axis image" is called only if the axes has only one child (the new image).
This is the way ML seams to work:
 - if the axes has only one image child its limits are set tight and equal whatever the "x/ylimmode".
 - else "x/ylimmode" values control whether or not limits are adjusted.

Should I add a test for the above behavior?

(file #30702)

Pantxo Diribarne <pantxo>
Group Member
Tue 25 Feb 2014 07:44:11 PM UTC, comment #8: 

@pantxo: If you could implement it that would be great.  I can review the patch, but am otherwise too swamped to do anything.

I'm not overly concerned about the 'axis equal' difference.  According to the Matlab documentation, this command is about making the x and y axes use equal length, not about setting the actual limits used.  For setting limits there is


axis ([xmin xmax ymin ymax])
xlim ([xmin xmax])
axis tight
axis image
axis auto



Rik <rik5>
Group administrator
Tue 25 Feb 2014 06:21:36 PM UTC, comment #7: 

If you'd like me to do some more testing (or even implement this), just let me know.

There will still be the discrepancy in "axis equal" after which the position of the axes should be the default. I'll look into this.

Pantxo Diribarne <pantxo>
Group Member
Mon 24 Feb 2014 05:12:26 PM UTC, comment #6: 

That's good news.  This means we can consolidate all the limit setting code in axis.m and remove the dubious FIXME and duplicate code from image.m.  As a bonus, this is all just m-file changes rather than messing with C++.

Rik <rik5>
Group administrator
Sun 23 Feb 2014 05:11:06 PM UTC, comment #5: 

Sorry my mistake, I didn't see that enlarging the limits manually let fltk draw the whole pixels with the expected colors.

In your example script "xlimmode" is "manual" in the 3 cases so I don't understand the comment and I'd say your approach will lead to the right result.
After fixing axis, image.m should use "axis (hax, 'image')" for the purpose of setting limits. This would avoid duplicating code.



Pantxo Diribarne <pantxo>
Group Member
Sun 23 Feb 2014 04:22:17 PM UTC, comment #4: 

This is what I thought.  The problem is not in the actual rendering by OpenGL but in Octave's selection of the axis limits.  Octave gets it right when you actually call 'image'.  See this code section from image.m


      px = __image_pixel_size__ (h);

      if (xdata(2) < xdata(1))
        xdata = fliplr (xdata);
      elseif (xdata(2) == xdata(1))
        xdata = xdata(1) + [0, columns(img)-1];
      endif
      if (ydata(2) < ydata(1))
        ydata = fliplr (ydata);
      elseif (ydata(2) == ydata(1))
        ydata = ydata(1) + [0, rows(img)-1];
      endif
      xlim = xdata + [-px(1), px(1)];
      ylim = ydata + [-px(2), px(2)];

      ## FIXME -- how can we do this and also get the {x,y}limmode
      ## properties to remain "auto"?  I suppose this adjustment should
      ## happen automatically in axes::update_axis_limits instead of
      ## explicitly setting the values here.  But then what information is
      ## available to axes::update_axis_limits to determine that the
      ## adjustment is necessary?
      set (hax, "xlim", xlim, "ylim", ylim);


_image_pixel_size_ is a C++ routine that, for the test image of 4 pixels, returns 0.5.  The axis limits are then set to the tight data limits (xdata) +/- the pixel size which results in limits of [0.5, 4.5].  This is perfect.

'axis image' is equivalent to 'axis tight' followed by 'daspect ([1 1 1])'.  One quick fix would be to change axis.m to use the same calculation routine for axis limits as above.  Even better would be to change the _get_tight_lims_ routine in axis.m so that it would take account of the graphic object type.  For all object types which were not images (line, surface, etc.) it could use the limits of the data.  For image types it would perform the calculation above.

Finally, there is that suspicious FIXME note in the code.  Octave sets the axis limits manually when doing a call to image().  What does Matlab do?


im=uint8([0 1 2 0; 0 1 2 0; 0 1 2 0; 0 1 2 0]);
map=[0 0 0; 1 0 0; 0 1 0; 0 0 1; 1 1 0; 0 1 1 ; 1 0 1];
im_dbl = double (im) + 1;
colormap (map);

image ([], [], im_dbl);
get (gca, 'xlimmode')
axis tight
get (gca, 'xlimmode')
axis image
get (gca, 'xlimmode')


Is the xlimmode 'manual' or 'auto'?


Rik <rik5>
Group administrator
Sun 23 Feb 2014 03:24:13 PM UTC, comment #3: 

Here is the result of the script slightly modified to show differences with octave behavior:


im=uint8([0 1 2 0; 0 1 2 0; 0 1 2 0; 0 1 2 0]);
map=[0 0 0; 1 0 0; 0 1 0; 0 0 1; 1 1 0; 0 1 1 ; 1 0 1];
im_dbl = double (im) + 1;
colormap (map);

image ([], [], im_dbl);
xlim1 = xlim
axis ('equal');
xlim2 = xlim
ylim2 = ylim
axis ('tight');
xlim3 = xlim
axis ('image');
xlim4 = xlim
clf;
imshow (im_dbl, map);
xlim5 = xlim

## result
xlim1 =
    0.5000    4.5000

xlim2 =
   -0.0358    5.0358

ylim2 =
    0.5000    4.5000

xlim3 =
    0.5000    4.5000

xlim4 =
    0.5000    4.5000

xlim5 =
    0.5000    4.5000


Indeed, in ML, axes limits include the half width of the pixels on the boundary when necessary.

Equal mode is different in octave but maybe those tests about xy/lim should be part of another bug report. AFAIU this bug is now mainly about octave openGL not being able render unint8 images properly.



Pantxo Diribarne <pantxo>
Group Member
Sun 19 Jan 2014 09:40:28 PM UTC, comment #2: 

With gnuplot, the correct colors are now shown in both 3.8.0 and the development version of Octave.

Still waiting on reporter or someone with access to Matlab to run Rik's script to determine default axis limits.

Mike Miller <mtmiller>
Group Member
Thu 07 Jun 2012 03:49:56 PM UTC, comment #1: 

There are several bugs interacting with each other here.

First, are you using FLTK or gnuplot as the graphics toolkit for imshow?  My guess is that you are using FLTK which has a strange issue here.

Second, full support for uint8 images will probably come in version 3.8.0 of Octave.  For the moment, it would be better to use images of class double.  To convert use the following:


im_dbl = double (im_uint8) + 1;


The addition of 1 is necessary because double images index into the colormap starting with 1, not 0.

Finally, it appears to me that the data has been correctly plotted but the axis limits are incorrect.  The test image/matrix you plotted had four values and so the xlimits were set at [1, 4].  The following command sets correct limits which reproduces the entire image.


xlim ([0.5, 4.5])


In order to help debug this, could you run the following code under Matlab?  I want to verify what axis limits get set.


im=uint8([0 1 2 0; 0 1 2 0; 0 1 2 0; 0 1 2 0]);
map=[0 0 0; 1 0 0; 0 1 0; 0 0 1; 1 1 0; 0 1 1 ; 1 0 1];
im_dbl = double (im) + 1;
colormap (map);

image ([], [], im_dbl);
xlim1 = xlim
axis ('equal');
xlim2 = xlim
axis ('tight');
xlim3 = xlim
axis ('image');
xlim4 = xlim
clf;
imshow (im_dbl, map);
xlim5 = xlim



Rik <rik5>
Group administrator
Tue 05 Jun 2012 01:48:43 PM UTC, original submission:  

The test program is as follows.

>>im=uint8([0 1 2 0; 0 1 2 0; 0 1 2 0; 0 1 2 0]);
>>map=[0 0 0; 1 0 0; 0 1 0; 0 0 1; 1 1 0; 0 1 1 ; 1 0 1];
>>imshow(im,map)


The result of Matlab is right. It will show a small image whose colors are black, red, green and black from left to right.
If using the "Octave with Visual Studio" version , the colors are just only black, red and black, and the spaces between colors are not equal.
If using Octave-3.6.1-mingw, it is totally white.

Fu Juay Chang <richerard>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #30702:  axistight_bug36594.patch added by pantxo (3KiB - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by richerard (Submitted the item)
  • -email is unavailable- added by richerard
  •  

    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 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2014-02-26 rik5 StatusNeed Info Fixed
        Open/ClosedOpen Closed
    2014-02-25 pantxo Attached File- Added axistight_bug36594.patch, #30702
    2014-01-19 mtmiller CategoryNone Plotting
        Release3.6.1 dev
        Operating SystemMicrosoft Windows Any
    2012-06-13 rik5 StatusConfirmed Need Info
    2012-06-07 rik5 StatusNone Confirmed
    2012-06-05 richerard Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code