bugGNU Octave - Bugs: bug #41851, ind2rgb values outside range of...

 
 

bug #41851: ind2rgb values outside range of colour map

Submitter:  Guillaume <gyom>
Submitted:  Thu 13 Mar 2014 12:30:44 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Guillaume 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

Tue 18 Mar 2014 02:09:26 AM UTC, comment #12: 

Okay, I went with your modification to the proposed changeset.  It's checked in on the default branch (http://hg.savannah.gnu.org/hgweb/octave/rev/875f4510d6dc).

Rik <rik5>
Group administrator
Tue 18 Mar 2014 12:11:24 AM UTC, comment #11: 

Rik, as an alternative, please take a look at the attached patch. It is an amend of yours.

It makes note of this bug number in the comments, prints a warning for the opposite case (colours above the cmap limit), and tests that warnings are issued for 0, off by one errors for integers and floats.

Also, it performs just a tiny little better (since we don't need isindex to check if all values are integers again) and avoids "x(x < 1) = 1" unless absolutely required which always creates a copy of the image.

(file #30934)

Carnë Draug <carandraug>
Group Member
Mon 17 Mar 2014 06:07:10 PM UTC, comment #10: 

Thanks Rik, works fine for me with the warning below being displayed for values < 1.

if (isfloat (x) && ! isindex (x))
  warning (["Octave:" caller ":invalid-idx-img"],
           [caller ": Indexed image contains colors outside of colormap."]);
endif


Guillaume <gyom>
Mon 17 Mar 2014 04:13:14 PM UTC, comment #9: 

Carne, I've attached a patch that makes Octave compatible with Matlab in this regard.  I don't like it much either though.  If someone tests the patch and verifies it I will check it in.

(file #30929)

Rik <rik5>
Group administrator
Mon 17 Mar 2014 03:16:02 PM UTC, comment #8: 

Matlab behaviour is plain wrong since the value for that index does not exist. If instead of an image this was a matrix for some other purpose, would you think appropriate to give you the last element of the matrix if you tried to index outside the limit of the matrix? And colours in a colourmap are not necessarily sorted by intensity.

In addition, "fixing" this will make it much easier for users to make "off by one" mistakes.

Still, we may not have much of a choice to introduce this error for the sake of matlab compatibility. So I'm reopened the bug and ask for opinion of others devs. Let us at least print a big fat warning if users try to index out of the bounds of the colourmap.

Carnë Draug <carandraug>
Group Member
Mon 17 Mar 2014 01:30:30 PM UTC, comment #7: 

Thanks once again.
I personally think that the MATLAB behaviour is appropriate here and could be implemented by having these lines in private/ind2x.m:


## Threshold out of range data
x = min (x, rows (map));
x = max (x, 1);


Guillaume <gyom>
Fri 14 Mar 2014 05:18:22 PM UTC, comment #6: 

Hmm... I see what you mean. Looking into private/ind2x.m function, there is:


  num_colors = rows (map);
  if (num_colors < maxidx)
    ## Pad with the last color in the map for Matlab compatibility
    pad = repmat (map(end,:), maxidx - num_colors, 1);
    map(end+1:maxidx, :) = pad;
  endif


Maybe we should also give an error for this cases? Or issue a warning?

Carnë Draug <carandraug>
Group Member
Fri 14 Mar 2014 12:06:57 PM UTC, comment #5: 

Thanks for your comments. I used the code with uint8() and double() because it is the exact one from the test cases.

Maybe I should use another example - in MATLAB you get this:

>> ind2rgb([-1 0 1 2 63 64 65 66],gray(64))
ans(:,:,1) =
         0         0         0    0.0159    0.9841    1.0000    1.0000    1.0000
ans(:,:,2) =
         0         0         0    0.0159    0.9841    1.0000    1.0000    1.0000
ans(:,:,3) =
         0         0         0    0.0159    0.9841    1.0000    1.0000    1.0000


while Octave will complain of values -1 and 0, but is OK with values beyond the size of the colormap:

octave> ind2rgb([1 2 63 64 65 66],gray(64))
ans =
ans(:,:,1) =
   0.00000   0.01587   0.98413   1.00000   1.00000   1.00000
ans(:,:,2) =
   0.00000   0.01587   0.98413   1.00000   1.00000   1.00000
ans(:,:,3) =
   0.00000   0.01587   0.98413   1.00000   1.00000   1.00000


So values larger than the size of the colormap are all reassigned to that value (in Octave and MATLAB). And only MATLAB assigns an index of 1 to all values less than 1.
It seems to me like a reasonable behaviour (symmetrical handling of both extrema) and compatible to what happens when you display an image with a fixed CLim axis (out of range values are assigned the first or last colors from the colormap).

Guillaume <gyom>
Thu 13 Mar 2014 11:03:55 PM UTC, comment #4: 

I second Rik's opinion.

Ignoring the case of the class explanation, you will notice that in your example, the indexed image has indices with a value of "zero" and "one" (the first and third row of the first column). From your example, it seems that Matlab assigns the same colour to both of them. How come two different indices give the same colour when there's no repeated colours in the colormap?

This is yet another case where Matlab returns rubbish due to improper input check. A matrix of class double is only an indexed image if all values are positive integers. Rather than returning a wrong answer, Octave gives an error. That sounds right to me so I'm marking this as invalid.

Another suggestion. Instead of using


img_double = double (img) + 1;


I'll instead recommend to use the image package which has a set of functions meant to convert an image between different types. If they are indexed, you can do


im2double (img, "indexed")


which handles all the details for you.

Carnë Draug <carandraug>
Group Member
Thu 13 Mar 2014 09:42:20 PM UTC, comment #3: 

I don't know what Matlab is doing, but I think Octave is correct in rejecting the variable img as not being an indexed image.

When the img is of type double, a 1 in the matrix points to the first row in the colormap.  When the img is an integer type, such as uint8, then an offset of 1 is used such that a 0 in the matrix points to the first row in the colormap.  See Matlab's own documentation for more information (http://www.mathworks.com/help/matlab/creating_plots/image-types.html).

In the posted code, the image is originally in uint8 format and thus has 0 values.  Using double() to convert a uint8 image is not correct.  You actually need to do


img_double = double (img) + 1;



Rik <rik5>
Group administrator
Thu 13 Mar 2014 05:46:50 PM UTC, comment #2: 

Sorry about that, I should have copied the exact code I used:


img = [2 4 5; 3 2 5; 1 2 4];
map = [0.0  0.0  0.0
       0.2  0.4  0.6
       0.4  0.4  0.5
       0.3  0.7  1.0
       0.1  0.5  0.8];
img = uint8 (img -1);
[rgb] = ind2rgb (double(img), map)


MATLAB returns:

rgb(:,:,1) =
         0    0.4000    0.3000
    0.2000         0    0.3000
         0         0    0.4000
rgb(:,:,2) =
         0    0.4000    0.7000
    0.4000         0    0.7000
         0         0    0.4000
rgb(:,:,3) =
         0    0.5000    1.0000
    0.6000         0    1.0000
         0         0    0.5000


while Octave dev returns:

error: ind2rgb: X must be an indexed image


Guillaume <gyom>
Thu 13 Mar 2014 05:20:44 PM UTC, comment #1: 

I am a bit confused by the bug report. Your first sample are the results you get in Matlab or Octave? I do not get an error, and it works correctly (althout not the results you are displaying). Using Octave 3.8.1:


img = [2 4 5; 3 2 5; 1 2 4];
map = [0.0  0.0  0.0
       0.2  0.4  0.6
       0.4  0.4  0.5
       0.3  0.7  1.0
       0.1  0.5  0.8];

ind2rgb (double (img), map)
ans =

ans(:,:,1) =

   0.20000   0.30000   0.10000
   0.40000   0.20000   0.10000
   0.00000   0.20000   0.30000

ans(:,:,2) =

   0.40000   0.70000   0.50000
   0.40000   0.40000   0.50000
   0.00000   0.40000   0.70000

ans(:,:,3) =

   0.60000   1.00000   0.80000
   0.50000   0.60000   0.80000
   0.00000   0.60000   1.00000


which should be the correct values.

Carnë Draug <carandraug>
Group Member
Thu 13 Mar 2014 12:30:44 PM UTC, original submission:  

The tests for ind2rgb return a different output in MATLAB for floating point inputs: (using variables from scripts/image/ind2rgb.m)


>> [rgb] = ind2rgb (double(img), map)
rgb(:,:,1) =
         0    0.4000    0.3000
    0.2000         0    0.3000
         0         0    0.4000
rgb(:,:,2) =
         0    0.4000    0.7000
    0.4000         0    0.7000
         0         0    0.4000
rgb(:,:,3) =
         0    0.5000    1.0000
    0.6000         0    1.0000
         0         0    0.5000


while Octave expects an error.
The other tests in "Test input validation" that do not return an error are:

>> ind2rgb (sparse (1), jet (64))
ans(:,:,1) =
     0
ans(:,:,2) =
     0
ans(:,:,3) =
    0.5625
>> ind2rgb (0, jet (64))
ans(:,:,1) =
     0
ans(:,:,2) =
     0
ans(:,:,3) =
    0.5625
>> ind2rgb (1, ones (2,2,2))
ans(:,:,1) =
     1
ans(:,:,2) =
     1
ans(:,:,3) =
     1
>> ind2rgb (1, ones (2,4))
ans(:,:,1) =
     1
ans(:,:,2) =
     1
ans(:,:,3) =
     1


Guillaume <gyom>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #30934:  ind2bug.cset added by carandraug (7KiB - application/octet-stream)
file #30929:  ind2x.cset added by rik5 (6KiB - application/octet-stream)

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by gyom (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 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-03-23 carandraug Dependencies- bugs #47506 is dependent
    2014-03-18 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2014-03-18 carandraug Attached File- Added ind2bug.cset, #30934
    2014-03-17 rik5 Attached File- Added ind2x.cset, #30929
        StatusNone Ready For Test
    2014-03-17 carandraug StatusInvalid / Not an Octave Bug None
    2014-03-14 carandraug Open/ClosedClosed Open
        Summaryind2rgb tests ind2rgb values outside range of colour map
    2014-03-13 carandraug Open/ClosedOpen Closed
    2014-03-13 carandraug StatusNone Invalid / Not an Octave Bug

    Back to the top

    Powered by Savane 3.14-d582.
    Corresponding source code