bwdist feature transform output is wrong class and imprecise?

5 views (last 30 days)
I am attempting to use the feature transform of bwdist, however, I find that the linear index IDs in the feature transform output do not match the linear index values of the input matrix. Secondly, the class of the output is single while the matlab website says that it should be uint32 or uint64. Is there something I am doing wrong?
Here is an example of what I am trying to do:
cellPos = rand(12000,12000);
cellPos(cellPos<.99999)= 0; % create ~ 1400 true instances in matrix
cellPos = logical(cellPos);
[cellDist, cellLabel] = bwdist(cellPos);
class(cellLabel) % should this be uint32?
cellID = find(cellPos); % linear index values of input matrix
ismember(cellID,cellLabel) % why is this not all 1's
Thank you for any help

Accepted Answer

Teja Muppirala
Teja Muppirala on 24 Aug 2012
After checking on this, you're right. In R2010b, it was returning IDX as a single, and because a single can only represent consecutive integers up to 2^24, it fails for large images that have more than this many pixels. This was changed in R2012a to return uint32/uint64 instead. The bwdist_old function might still work though.

More Answers (1)

Image Analyst
Image Analyst on 22 Aug 2012
[D,IDX] = bwdist(BW)
BW can be numeric or logical, and it must be nonsparse. D is a single matrix with the same size as BW. The class of IDX depends on the number of elements in the input image, and is determined using the following table.
So the web site says it will be single, and it is. Where do you see that the "website says that it should be uint32 or uint64"?
  3 Comments
Teja Muppirala
Teja Muppirala on 23 Aug 2012
From the documentation: [D,IDX] = bwdist(BW)
From your command: [cellDist, cellLabel] = bwdist(cellPos);
So, in other words,
cellDist <--> D
cellLabel <--> IDX
The first one "cellDist" (D) represents actual distance. It is a real number like 17.2313 or 78.8342 or 65.4539. The documentation says that D is a single precision matrix. If you type
class(cellDist)
you will find that it is in fact a single precision matrix.
On the other hand, "cellLabel" (IDX) refers to index values. These are positive integers like 5623 or 9831 or 815. Since these are always going to be positive integers, it makes sense to store them as an unsigned integer datatype. UINT32 can store up to 2^32-1, which is the maximum index that you could get out of about a 4 gigapixel image. The documentation says the class of IDX will be uint32, and as you can see
class(cellLabel)
is indeed uint32. So there is nothing weird or inconsistent here.
As far as why this:
ismember(cellID,cellLabel)
is not all ones, I am not able to reproduce your results. It certainly gives all ones for me. What MATLAB version are you using? Does the following code not give you ans = 1?
rng(0); % Fix the random number state for repeatability
cellPos = rand(12000,12000);
cellPos(cellPos<.99999)= 0; % create ~ 1400 true instances in matrix
cellPos = logical(cellPos);
[cellDist, cellLabel] = bwdist(cellPos);
cellID = find(cellPos);
all(ismember(cellID,cellLabel))
Adam
Adam on 23 Aug 2012
Edited: Adam on 23 Aug 2012
I am running MATLAB Version 7.11.0.584 (R2010b) Operating System: Microsoft Windows XP x64 Version 5.2 (Build 3790: Service Pack 2)
I am not able to fix the random number state using 'rng', I get the following error
??? Undefined function or method 'rng' for input arguments of type 'double'.
If I run the rest of the code, without setting the random number generator, I still get:
class(cellLabel)
single
and all(ismember(cellID,cellLabel))
0
Is it simply that bwdist was updated in a newer version?
In the initial answer above it was stated that IDX should be single as it says in the documentation. I find that when I get the documentation for bwdist by entering
help bwdist
into the command line
I get the following
... Class support ------------- BW can be numeric or logical, and it must be nonsparse. D and L are single matrices with the same size as BW. ...
however, this is different than what is found on the matlab website.
One last thing: I looked at the documentation for bwdist_old
and the class support is stated as:
% Class support % ------------- % BW can be numeric or logical, and it must be nonsparse. D and L are % double matrices with the same size as BW.
This makes me think that the output was changed from double to single for speed at some point, and then likely changed to uint32 and uint64 at a later time for accuracy. Can you tell me which version of matlab you are running, which is giving you class(uint32) as an output for IDX?

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!