2

I am trying to experiment how MatLab image processing methods work when I came across this problem. Please refer to the 2 images below The images are actually the sides of books:

enter image description here enter image description here

The image on the right shows a failed effort to bound and count the number of object. The code is as follows:

BW2=~BW2;
imshow(BW2)
B = bwboundaries(BW2);
imshow(BW2)

text(10,10,strcat('\color{green}Objects Found:',num2str(length(B))))
hold on

for k = 1:length(B)
boundary = B{k};
plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 0.2)
end

This method is adopted from http://www.instructables.com/id/Image-Processing-and-Counting-using-MATLAB/step5/Find-the-Boundaries-of-the-Objects/

But as you can see, it doesn't work all the time. Only approximately half the time then it will work. Do anybody know how I can improve the counting? or is there another method to count blobs from an image like that?

I did this successfully using OpenCV cvBlob library before. But when it comes to MatLab, I am a greenhorn, hence hope somebody can assist me on this. Thanks.

4
  • 1
    I recommend reading some basic image processing concepts like thresholding, image morphology and connected components analysis to make sure you understand what you are doing. Commented Oct 25, 2013 at 13:01
  • 1
    Why does it fail? Is it not properly applying the boundries or is it actually counting the white parts instead of the black? Commented Oct 25, 2013 at 13:13
  • @zoran, I do have basic image processing concepts like thresholding, etc, however, when it comes to connected component, my knowledge is limited. I will read up more on it. Thanks for the suggestion. I usually use opencv to do my image processing, and I am trying to redo most of the programs I done in OpenCV with MatLab to understand how MatLab works. This program is one of them. Commented Oct 25, 2013 at 19:11
  • @DennisJaheruddin, True, I did not consider whether it is actually counting the white parts instead of the black, have been a tired down by my school. Thanks. I will look into it again. Commented Oct 25, 2013 at 19:12

2 Answers 2

1

First of all, if you only need to know the number of blobs, and you do not need their boundary pixels, then bwboundaries is an overkill. Instead, you can use bwconncomp, which will just find and label the blobs.

Second, it seems that the biggest problem here is that you are inverting the mask. So you are actually trying to find connected components in the background, instead of in the foreground. You are counting empty spaces between the books, instead of the books themselves. So don't do BW2=~BW2;

Finally, there are may be blobs in the image that are caused by noise, and not books. So you need to either reject blobs that are too small, or do some preprocessing on the mask before hand. For example, you can try morphological opening to get rid of small isolated clumps of foreground pixels.

P.S. Also please take a look at the regionprops function. You may find it useful.

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks! Doing BW2=~BW2 was the cause of it. Will choose your answer as the accepted one soon, but before I do that, I hope its not too crude of me for a suggestion on how to retrieve the number of blobs from bwconncomp? I switched to bwboundaries as bwconncomp wasn't giving me the result. Tried cc.NumObjects, etc, but failed. I am able to make all the blobs to different colours, but the documentation and examples available on bwconncomp from the internet is too little for me to try implemented what you suggested. I have been trying for a 2 full days already. Hope you can help. Thanks!
cc.NumObjects should do it. Were you trying it before or after you stopped inverting the mask? Also, if you need to get centroids or bounding boxes of the blobs, then use regionprops.
Tried both before and after inverting the mask. But get super huge results like 3631. Do you have any idea where I could have gone wrong? My code is cc = bwconncomp(BW, 4); stats = regionprops(cc, 'Area'); idx = find([stats.Area] >250000); BW2 = ismember(labelmatrix(cc), idx); cc.NumObjects;
Hmm... NumObjects could be large, if you have a lot of small specks in the image. What is the size of idx? That should be a reasonable number, since you are only counting large blobs. Also, do try preprocessing the mask using imopen or bwmorph.
the idx values printed are = 1 74 110. That's the thing that is puzzling me! I am only looking at blobs that have an area of 250000, and removed all the small specks in the image already. In addition, I have also tried methods like imdilate, imfill to make sure there is no such little specks, yet the results returned from cc.NumObjects is too big. Should I start another question on stackoverflow dedicated to this problem?
|
1

Here is one thing you can try, I expect this to work for at least the second failed example:

Rather than only analysing the entire image at once, consider cutting it up and then analysing it.

Suppose you cut it into 5 columns (assuming the books are always lying down) then you can perform the analysis 5 times. Afterwards you can take the median for example, and hopefully get a more accurate result.

1 Comment

Yup. That will be one of the programs I will do later on in this image. Now I am trying to to redo most of the programs I done in OpenCV with MatLab to understand how MatLab works. Your suggestion is actually one of the programs I done before via OpenCV. Yet to try on MatLab. Trying to solve this problem first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.