The next step after turning to binary image

Hello, I'm a student currently doing an assignment. I have asked the steps to classify image (ripe and unripe tomatoes) before, and Image Analyst suggested a good way to do it. But my lecturer did not want me to use the solution, since it uses Image processing Toolbox and she said I might not learn the basics from it. Anyway, she suggested to me to :
1. turn the rgb image of the tomatoes into grayscale image
2. create a histogram of the grayscale image (in which I modified some of Image Analyst codes, thank you for that).
3. Determine the threshold from this histogram, which I don't think I understand, please help regarding this.
4. Use the threshold to change the grayscale image into binary image (since I was not sure how low or high the threshold is, I just guess. Is there any way to automatically adjust the threshold according to image?
5. From the o's and 1's of the binary image, find the coordinates for the x and y axis (I don't understand one bit, and it is currently weekend in my place).
In the lines below I have attached my code, and I really hope anybody who reads this could provide an insight to help me. My thanks in advance.
tomato = imread('tomatoes\ripe15.png');
grayimage = rgb2gray(tomato);
subplot(3, 1, 1),imshow(grayimage);
[pixelcount graylevels]=imhist(grayimage);
subplot(3, 1, 2);
bar(graylevels,pixelcount,'barWidth',1.0);
imhist(grayimage);
grid on;
xlim([0 graylevels(end)]); % Scale x axis manually.
title('Histogram of original image');
binaryimage=(grayimage>64);
%binaryimage = grayimage > 64; % or whatever value you want.
subplot(3, 1, 3);
imshow(binaryimage, []);

 Accepted Answer

imshow() is in base MATLAB now so you're okay there. But you'll have to replace imhist() and bar() with histogram().
To get the coordinates from the binary image, do this:
[rows, columns] = find(binaryImage);
however doing this does not group the coordinates by blob. Since you can't use bwlabel() you'll need to write a connected components labelling program yourself. Your teacher wants to torture you I'm sure. It's not easy.
To get the threshold, just inspect the histograms from a bunch of ripe and unripe images and take your best guess. You would want to use fixed thresholds, not ones that vary by image. Assuming that the images all have the same exposure and color balance, the ripe/unripe colors won't change. If they do, you'd need a color standard in each image. After all, if you put a ripe tomato under yellow sodium vapor lights and it will look ghastly unripe and diseased.

13 Comments

I'm sorry if I unintentionally confused you. What I meant by her telling me not to use IPT is like using it to change color space from RGB to HSI, since not understanding how things work could fail this subject. She told me to do that by calculations rather than use IPT. Sorry again. Ok for now let's just assume she allows me to use IPT and bwlabel().
By the way, the images I currently use have black background, if that helps. In her sketch she showed me an algorithm, which I can't understand much, like this :
if p(x)<50 %example
k(x)=1
else
k(x)=0
Is this related to the histogram in any way? I'm thinking it's the same as your variables
p = graylevels k = pixelcounts
She's creating a binary image in the way a C programmer would create it, not a MATLAB programmer. A MATLAB programmer would do
binaryImage = p < 50;
and not have a loop over k. The only way that's related to the histogram is that they found the value of 50 by looking at the histogram. However if you have a black background, it's possible graythresh might give you the value of 50:
thresh = 255 * graythresh(grayImage);
You can find formulas for color space conversion at easyrgb.com or at http://www.brucelindbloom.com/
ok I'm going to try graythresh for now, as well as bwlabel and see where I can go from there. Based on the code you provided, I think I understand that graythresh could somehow find the desired threshold value for me?
Furthermore, I've tried
binaryimage=(grayimage<64);
and I could get the image, but if I use graylevels, I can't seem to create any image, why so?
You need to determine the range of your gray scale image and use a threshold appropriate for that range. is the range 0-1 (double) or 0-255 (uint8) or 0-65535 (uint16)?
The range is 0-255 I think, since the bin (the yellow variables in workspace, not sure if that's the name) has range from 0-255 only. So where does this lead to?
Well then I don't know what you're saying in that you get an image but don't get an image if you use gray levels. What do you think 64 is? It's a gray level!
well, mind blown (sarcastic to myself). Sorry I seem to have lost myself there. Ok let me summarize the steps I need to make, please correct me if I'm wrong :
1. I got the grayscale image, so now I just need to run graythresh and im2bw, but I'm not sure if the difference is that much from just manually deducting graylevels value. By the way I got 'level' value of 0.2784, which could mean 27.84%.
level=graythresh(grayimage);
binaryimage = im2bw(grayimage,level);
imshow(binaryimage, []);
2. After I finish my graythresh predicament, where and how does bwlabel come to play? From what I've read, it can be used to find connected objects, is it to separate the tomato from the background?
Thanks again, I hope these questions are not too much.
Assuming there is only tomato in the scene and it's the biggest object thresholded, then use imfill() and bwareafilt() to extract it.
binaryimage = imfill(binaryimage, 'holes');
binaryimage = bwareafilt(binaryimage, 1);
Now you have a mask for the tomato and can use it to extract the mean LAB values or RGB values.
labImage = rgb2lab(rgbImage);
LImage = labImage(:,:,1);
AImage = labImage(:,:,2);
BImage = labImage(:,:,3);
meanL = mean(LImage(binaryimage));
meanA = mean(AImage(binaryimage));
meanB = mean(BImage(binaryimage));
Similar for RGB or HSV - whichever color space you're segmenting in.
Is there any way to filter without bwareafilt? I only have matlab2010a. Will sobel filter work?
Oh my god, I just realized that rgb2lab is also in a version ahead of my matlab version. Guess I just have to use the math calculations for HSI then. Am I right?
Update #1:
Based on your guide on separating blobs to make mask in this link here I think I know what to do after getting the graythresh.
1. use bwlabel to get measurements and calculate the largest blob (the single tomato).
2. Extract the largest using the function you built (extractNlargestblobs()), hope you allow me to use it.
3. The third step however is confusing, I'm guessing you want me to apply some sort of mask from the blob, into the HSI image I created so that I can extract mean HSI values?
You can use my function or you can use bwareaopen() - they're slightly different.
Update #2
My lecturer asked me to find the mean without using toolbox of course (since I need it to obtain threshold, graythresh isn't applicable in this project either), and I have typed some codes, with her help of course, but there is something wrong with this code, and I can't seem to get the value of "total".
tomato = imread('tomatoes\ripe13.png');
grayimage = rgb2gray(tomato);
total=0;
x=0;
y=0;
[m n]=size(grayimage);
for x=1:m
for y=1:n
total=total+grayimage(x,y);
end
end
avg=(total)/(x*y);
subplot(3, 1, 1),imshow(grayimage);
Make it double:
total=total+ double(grayimage(x,y));
otherwise it stays uint8 and clips to 255 - the sum can't go higher.
I have understood your suggestion, and it can finally get the average with the total, and I have also created a binary image with it. But I have to ask, since all these loops are computationally expensive (I mean like, a lot, since I have to use another loop to obtain the binary image), is there any way to improve it? It seems like an interesting thing to learn, since matlab suggests using their vectorization method which I could not seem to understand applying to image.
These are the codes, which you can see, is very expensive :
binaryimage=size(grayimage(:));
for coordx=1:grayX
for coordy=1:grayY
%this is done to threshold the grayscale image according to
%the mean, that is avg
if (grayimage(coordx,coordy)>avg)
binaryimage(coordx,coordy)=1;
else
binaryimage(coordx,coordy)=0;
end
end
end

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!