patchGNU Octave - Patches: patch #8812, Added imquantize to image toolset

 
 

patch #8812: Added imquantize to image toolset

Submitter:  None
Submitted:  Fri 27 Nov 2015 11:14:48 PM UTC
   
 
Category:  None Priority:  5 - Normal
Status:  Done Privacy:  Public
Assigned to:  None Originator Email:  -email is unavailable-
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 03 Dec 2015 02:27:08 PM UTC, comment #10: 

It seems to me that you're reading the arguments in lookup as the same order as imquantize. The only thing that needs to be monotonic is the TABLE, and the TABLE is the imquantize's LEVELS arguments.  The call to lookup() has the arguments swapped.

I have pushed http://hg.code.sf.net/p/octave/image/rev/90a52e024691 please take a look at the code.

I have also extended and corrected your original tests (they were not Matlab compatible). But please ping here with a test case if you find it's not behaving correctly. As far as I could test it, it was correct.

Carnë Draug <carandraug>
Group Member
Wed 02 Dec 2015 08:23:54 PM UTC, comment #9: 

It does seem to work for the special case in which you only want to label regions and not assign them costume values.

But it shouldn't work according to the documentation... in fact, I can't see how the documentation on this function is correct.

Did I miss anything?

From help lookup:


If table is increasing and 'idx = lookup (table, y)', then
     'table(idx(i)) <= y(i) < table(idx(i+1))' for all 'y(i)' within the
     table.  If 'y(i) < table(1)' then 'idx(i)' is 0.  If 'y(i) >=
     table(end)' or 'isnan (y(i))' then 'idx(i)' is 'n'.

     If the table is decreasing, then the tests are reversed.  For
     non-strictly monotonic tables, empty intervals are always skipped.
     The result is undefined if TABLE is not monotonic, or if TABLE
     contains a NaN.

     The complexity of the lookup is O(M*log(N)) where N is the size of
     TABLE and M is the size of Y.  In the special case when Y is also
     sorted, the complexity is O(min(M*log(N),M+N)).

Guy B <motherboard>
Wed 02 Dec 2015 02:35:16 PM UTC, comment #8: 

Are you sure of that? That imquantize can't be replaced with lookup? I just gave it a go, and it passes all of your tests. See what I get using lookup(), even when the image values are scrambled:


img = [1:10; 11:20; 21:30; 31:40; 41:50; 51:60; 61:70];
idx = reshape (randperm (numel (img)), size (img));
img_s = img(idx);
quant = imquantize (img, [5 15 25 30 40 60]);
quant_s = imquantize (img_s, [5 15 25 30 40 60]);
isequal (quant_s, quant(idx))

ans =  1


I have attached my implementation (two lines if you remove input check).

(file #35615)

Carnë Draug <carandraug>
Group Member
Wed 02 Dec 2015 12:05:00 AM UTC, comment #7: 

Maybe I wasn't clear enough...
imquntize cannot be replaced by lookup even for

        imquantize(img, [1 5 9])

Unless img is ordered from lowest to highest.

Guy B <motherboard>
Tue 01 Dec 2015 09:05:28 PM UTC, comment #6: 

Oops, don't change the code.
Just had a look at lookup - it would be the same only for monotonically increasing table.

Anonymous
Tue 01 Dec 2015 08:55:33 PM UTC, comment #5: 

It does solve one of the usage scenarios, but not the one in which you provide costume values.

It would improve the code a bit to use lookup for the special case in which no values variable is given, though.

You're welcome to make that change.

Anonymous
Tue 01 Dec 2015 05:03:01 PM UTC, comment #4: 

It seems to me that this function could be reduced to one line by making use of lookup() ?

Example:


octave > lookup ([1 5 9], 1:10)
ans =

   1   1   1   1   2   2   2   2   3   3


Carnë Draug <carandraug>
Group Member
Mon 30 Nov 2015 08:48:39 PM UTC, comment #3: 

Fixed documentation, added example for usage.
Values of input image are no longer assumed to be in the range 0-255.
Added tests, and demo.

(file #35602)

Guy B <motherboard>
Mon 30 Nov 2015 02:49:03 PM UTC, comment #2: 

1. I will change the heading,  didn't know something as trivial as function documentation would be an issue.
2. The email given is, in fact, my real email... and Motherboard is my alias in github...
3. How do I add tests?

Guy B <motherboard>
Mon 30 Nov 2015 02:24:10 PM UTC, comment #1: 

This submission has 3 issues:

1. the whole documentation has been copied verbatim (only converted to Texinfo) from Matlab which is an issue. The whole piece of work (both code and documentation), must belong to you and not copied from Mathworks.

2. we will need your name and email for the copyright. Motherboard <cantfind@gmail.com> seems like an attempt at never be contacted again. It is fine if you want an alias and need to remain anonymous, but we need something to identify and contact you in the future.

3. the function is new and needs some tests.

Carnë Draug <carandraug>
Group Member
Fri 27 Nov 2015 11:14:48 PM UTC, original submission:  

Attached is the diff patch,
following is the content of the m file submitted in the commit.
Please add it to the image toolset.

## Copyright (C) 2015 Motherboard
##
## This program is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Library Function} {@var{quantImg} = mat} imquant (@var{img} mat, @var{levels} vector, @var{values} vector)
##  quant_A = imquantize(A,levels) quantizes image A using specified quantization values contained in the N element vector levels. Output image quant_A is the same size as A and contains N + 1 discrete integer values in the range 1 to N + 1 which are determined by the following criteria:
##  If A(k) ≤ levels(1), then quant_A(k) = 1.
##  If levels(m-1) < A(k)  ≤  levels(m) , then quant_A(k) = m.
##  If A(k) > levels(N), then quant_A(k) = N + 1.
##  Note that imquantize assigns values to the two implicitly defined end intervals:
##  A(k) ≤ levels(1)
##  A(k) > levels(N)
##  example
##  quant_A = imquantize(_,values) adds the N + 1 element vector values where N = length(levels). Each of the N + 1 elements of values specify the quantization value for one of the N + 1 discrete pixel values in quant_A.
##  If A(k) ≤ levels(1), then quant_A(k) = values(1).
##  If levels(m-1) < A(k)  ≤  levels(m) , then quant_A(k) = values(m).
##  If A(k) > levels(N), then quant_A(k) = values(N + 1).
##  example
##  [quant_A,index] = imquantize(_) returns an array index such that:
##  quant_A = values(index)
## @seealso{}
## @end deftypefn

## Author: Motherboard <cantfind@gmail.com>
## Created: 2015-11-27

function [quantImg, index] = imquantize (img, levels, values)
  N = length(levels);
  if ~exist("values","var")
    values = 1:(N + 1); %if no values were given, set values to be labels.
    valuesPresent = false;
  elseif (length(values) ~= N + 1) %if values were given, make sure we have exactly the right amount.
    error("values should have length of levels + 1")
  else
    valuesPresent = true; %if values were given, and everything is fine, we might need to calculate the output index.
  endif
  quantImg = zeros(size(img));
  if isargout(2)          %if index is required, initialize it.
    index = quantImg;
  endif
  if (size(levels,1) == 1)  %check if levels is a column or a row vector to concatinate it correctly with 0 on one side, and 256 on the other.
    levels = [0; levels; 256];
  elseif (size(levels,2) == 1)
    levels = [0 levels 256];
  else
    error("levels should be a vector")  %make sure levels is a vector
  endif
  for i = 1:(N+1)
    indicesToAssign = img >= levels(i) & img < levels(i+1);  %compute the indices to be assign.
    quantImg(indicesToAssign) = values(i);
    if (isargout(2) && valuesPresent)   %if index is required, and values were given, assign labels to index.
      index(indicesToAssign) = i;
    endif
  end
  if (isargout(2) && ~valuesPresent) %if index is required, but values were not given, index is identical to quantImg
    index = quantImg;
  endif 
endfunction

Anonymous

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #35615:  imquantize.m added by carandraug (2KiB - text/x-matlab - implementation using lookup())
file #35602:  imquantize.diff added by motherboard (15KiB - text/x-patch)
file #35581:  imquantize.diff added by None (4KiB - 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 motherboard (Posted a comment)
  •  

    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 logged-in users can vote.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-12-03 carandraug StatusNone Done
    2015-12-03 carandraug Open/ClosedOpen Closed
    2015-12-02 carandraug Attached File- Added imquantize.m, #35615
    2015-11-30 motherboard Attached File- Added imquantize.diff, #35602
    2015-11-27 None Attached File- Added imquantize.diff, #35581

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code