2

enter image description hereI am trying to use DIPimage to get some measurements of each object in an image and I get this error:

Error using dip_measure
DIPlib Error in function dip_Measure.
DIPlib Error in function dip_ImageCheck: Data type not supported


Error in measure (line 209)
data = dip_measure(object_in,gray_in,measurementID,objectIDs,connectivity);

Error in Untitled (line 13)
msr = measure(b, [], ({'size', 'perimeter','podczeckShapes'}))

How can I solve it?

Code:

Image = rgb2gray(imread('pillsetc.png'));

BW = imbinarize(Image);
BW = imfill(BW,'holes');
imshow(BW);

[B,L] = bwboundaries(BW,'noholes');
k = 1;
b = B{k};
y  = b(:,2);
x  = b(:,1);

msr(k) = measure(BW, [], ({'size', 'perimeter','podczeckShapes'}))
sz = msr.size;
podczeckShapes = podczeckShapes;
Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
jane
  • 567
  • 2
  • 12
  • Did you check the documentation? Second argument is expected to be an image or `[]`, so in your case I would try `BW` or `[]` – Daniel Apr 12 '20 at 13:53
  • Using the code: msr = measure(BW,[], ({'size', 'perimeter','podczeckShapes'})) I get only the first object(I presume so) and I want to for a selected object for example. I updated the question – jane Apr 12 '20 at 14:07
  • I don’t know what your image looks like, but if `BW` is a binary image where the objects are 1 and the background 0, then `measure(BW,...)` should give you the right result. You are passing a vector of coordinates where an image is expected. `msr(6).size` will give the size of the 6th object. – Cris Luengo Apr 12 '20 at 14:47
  • Ok. I updated the code, is it fine?. Now I get this error. Anyway to by pass it? 'measure' requires DSP System Toolbox. Error in Untitled (line 13) msr = measure(BW, [], ({'size', 'perimeter','podczeckShapes'})) – jane Apr 12 '20 at 15:17

1 Answers1

1

One problem with your code is the call to imfill. Because the image has bright values all around the image, it is considered that there's a large object with a hole, and your actual objects are inside this hole. imfill fills the hole, leaving the whole image white.

Instead, I suggest the following code to remove the frame:

Image = rgb2gray(imread('https://i.stack.imgur.com/fmqAF.jpg'));
BW = imbinarize(Image);

BW = BW - bpropagation(false(size(BW)), BW);

Because we used a filter in DIPimage, the BW variable now contains a dip_image object, not a normal MATLAB array. dip_array(BW) extracts the normal MATLAB array that is inside. The dip_image object behaves differently from a MATLAB array. For example, you can display it to an interactive figure window by just typing its name:

BW

Next, we apply labeling so that we know which object ID in the measurement data corresponds to which object:

lab = label(BW);
dipshow(lab,'labels')

Now we can apply the measurement function. If we use BW as input, label will be called on it. Since we already have that result, let's use it directly:

msr = measure(lab, [], {'size', 'perimeter','podczeckShapes'});

Let's examine results for object ID 8, which is the large square:

sz = msr(8).size
square = msr(8).podczeckShapes(1)
triangle = msr(8).podczeckShapes(3)

There are other things you can do with the measurement structure, I suggest you read the documentation. For example, we can remove from it the measurement for the littlest objects, which to me look like noise:

msr = msr(msr.size>100); % remove measurement for noise
Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Thanks. DIPimage looks very cool. As I have already a code that use BW (Matlab array) how can I convert it to BW of dip_image object without doing any changes? Does the labeling in dip_image is the same as in regionprop (detecting objects from left to right)? How can I plot a number in the centroid of each object? – elyraz Apr 13 '20 at 07:37
  • @elyraz: You don't need to convert a MATLAB array to use it with DIPimage functions, they can all work equally well with MATLAB arrays as input. But they always output images as `dip_image` objects. To convert a matrix to a `dip_image` object use the `dip_image` constructor: `imgage=dip_image(array)`. To convert back use the `dip_array` function: `array=dip_array(image)`. Neither of these two functions copies data, so the conversion is cheap. – Cris Luengo Apr 13 '20 at 13:57
  • @elyraz: The order in which objects are labeled is likely different in `label` and `regionprops`. But you can put the result of `label` into `regionprops`: `lab=label(image); data=regionprops(dip_array(lab),...)`. To show label IDs on top of each object, use `displaylabelnumbers`. If you want to plot other numbers, you can copy that file and modify it. Another way to visualize numbers is `msr2obj`, which assigns the value of a property to each object pixel. Now you can use the interactive image display to look at the value of the property for each object. – Cris Luengo Apr 13 '20 at 13:58