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


patch #8812: Added imquantize to image toolset

Submitted by:  None
Submitted on:  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

Add a New Comment (Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


( 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 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>
Project 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>
Project 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.

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.

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() ?


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

   1   1   1   1   2   2   2   2   3   3

Carnë Draug <carandraug>
Project 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 <> 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>
Project 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
## 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 <>.

## -*- 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 <>
## 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")
    valuesPresent = true; %if values were given, and everything is fine, we might need to calculate the output index.
  quantImg = zeros(size(img));
  if isargout(2)          %if index is required, initialize it.
    index = quantImg;
  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];
    error("levels should be a vector")  %make sure levels is a vector
  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;
  if (isargout(2) && ~valuesPresent) %if index is required, but values were not given, index is identical to quantImg
    index = quantImg;



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

Attach Files:

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)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    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.6