Rice Classification
This example of Matlab attempts to show how can we do Image Analysis by segmenting and classifying objects in an image.
This program counts the number of rice present in an image. In addition, the average and standard deviation of the size are computed.
WARNING: the presented solution is very simple. The goal of this code is to show how can we use Matlab in Image Analysis. Obviously, better results can be obtained using more complex algorithms.
Computer Vision Course
(c) Domingo Mery (2014) - http://dmery.ing.puc.cl
Contents
1. Image acquisition
In this part, we read a digital gray-scale image, and we store it in a matrix using two formats:
a) 'uint8' for bytes (uint8: unsigned integer with 8 bits) and
b) 'double' for double precision.
close all % All figures are closed clear all % All variables are deleted U = imread('rice.png'); % Read image rice.png I = double(U); % Conversion to double
2. Image display
In this part, we display the image using grayscale and 3D representations. In addition, we label the axes.
figure % Open new figure imshow(I,[]) % Display image I: min(I) is black max(I) is white title('rice.png') % Title of the figure xlabel('j'); % Name of the x-axis ylabel('i'); % Name of the y-axis figure % Open new figure mesh(I) % 3D mesh surface view(129,78) % view point title('3D representation') % Title of the figure xlabel('j'); % Name of x-axis ylabel('i'); % Name of y-axis zlabel('Gray-values'); % Name of z-axis axis([0 255 0 255 0 255]); % Range of x,y,z in 3D representation
3. Histogram
In this part, we compute the histogram of the image, i.e., how many pixels we have in the image for each gray-value.
figure % Open new figure imhist(U) % Histogram of uint8 image title('Histogram') % Title of the figure xlabel('Gray-values'); % Name of x-axis ylabel('Frequency'); % Name of y-axis text(1,300,'background') text(200,300,'rice') text(120,900,'rice & background')
4. Segmentation using a global threshold
In this part, we compute a binary image B by thresholding.
In this case, B(i,j) = 1 if I(i,j)>th, else B(i,j) = 0. Ideally, B(i,j) = 1 if the pixel (i,j) belongs to the rice region, and it is 0 if it belongs to the background.
However, a global threshold does not segment well the image because the certain gray-values of the background (top of the image) are similar to certain gray-avlues of the rice (bottom of the image).
for th = 50:60:170 % th takes 50, 50+60=110 and 170 figure B = I>th; % Binary image: '1' for gray-values>th imshow(B) s = sprintf('Segmentation for th = %d',th); title(s); end
5. Background elimination
Since the background is not homogoneous (the top is brighter than the bottom), in this part, we attemp to set the background to zero. Thus, each row will be updated by subtracting its minimal value.
[N,M] = size(I); J = zeros(N,M); for i=1:N row_i = I(i,:); % vector that contains the i-th row of I mi = min(row_i); % minimal value of i-th row J(i,:) = row_i-mi; % each row is decreased by its minimum end figure imshow(J,[]) title('Image with zero background')
6. Segmentation of the new image
In this part, we segment the new image (with zero background) using a global threshold. First, we display the histogram where background and forground are clearly distinguishable. Second, we display the new binary image using a threshold = 40.
figure imhist(uint8(fix(J))) title('Histogram with zero background') xlabel('Gray-values'); ylabel('Frequency'); text(30,1000,'background') text(110,500,'rice') figure K = J>40; % pixels which gray-values are greater than 40 are segmented imshow(K) title('Segmentation using threshold and zero background');
7. Elimination of small regions (isolated pixeles)
We observe that the new segmentation image has isolated pixels. They correspond to noise in the background. In this part, we eliminate those pixles using command 'bwareaopen'.
T = bwareaopen(K,20); % regions which size is less than 20 pixels are eliminated figure imshow(T) title('Segmentacion without isolated pixels')
8. Labeling of regions
In order to perform a pattern recognition approach (with feature extraction and classification), we label each isolated region using the command 'bwlabel'.
L = bwlabel(T); % We assign a label to each region n = max(L(:)); % Number of regions figure imshow(L,[]) % Each region has a different gray-value title('Labeled regions') hold on
9. Feature extraction
In this part, for each labeled region we compute the size (area in pixels) and the center of mass (x,y in pixels). The area will be used in the classification. The location (x,y) will not be used in the classification, it will be used only for printing the label number of each rice.
A = zeros(n,1); % Area x = zeros(n,1); % Location x y = zeros(n,1); % Location y for i=1:n R = L==i; % Binary image '1' means pixel belongs to region i [ii,jj] = find(R==1); % Coordinates of each pixel of region i A(i) = length(ii); % Area of region i x(i) = mean(jj); % x value of center of mass of region i y(i) = mean(ii); % y value of center of mass of region j text(x(i),y(i),num2str(i)) end
10. Classification of regions
In this part, we attempt to classify each region in one of three classes: XS (extra-small), OK and XL (extra-large). XS regions correspond to regions that are incomplete (e.g. region 95). XL regions correspond to regions that are joined (e.g. region 55).
IXS = zeros(N,M); % Image with XS rice IXL = zeros(N,M); % Image with XL rice IOK = zeros(N,M); % Image with OK rice t = 0; % count of segmented regions AOK = zeros(n,1); % area of segmented regions for i=1:n R = L==i; % We look for region i a = A(i); % Area of region i if (a<100) % XS regions IXS = or(IXS,R); % Adding XS regions else if (a>300) % XL regions IXL = or(IXL,R); % Adding XL regions else IOK = or(IOK,R); % Adding OK regions t = t + 1; AOK(t) = a; end end end
11. Results
In this part we display the results. One image for each class. In addition, we display the histogram of area, and average size and standard deviation.
figure imshow(IOK) title('OK rice'); figure imshow(IXS) title('XS rice'); figure imshow(IXL) title('XL rice'); figure hist(A) hold on plot([100 100],[0 50],'r:') plot([300 300],[0 50],'r:') title('Area Histogram'); xlabel('Area [pixels]'); ylabel('Frequency'); text(30 ,30,'XS'); text(130,30,'OK'); text(350,30,'XL') p = mean(AOK(1:t)); % mean of the segmented regions s = std(AOK(1:t)); % standard deviation of segmented regions disp('Statistics of OK rice:') fprintf(' > Count: %d\n',t) fprintf(' > Average area: %6.2f [pixels]\n',p) fprintf(' > Standard deviation: %6.2f [pixels]\n',s)
Statistics of OK rice: > Count: 83 > Average area: 195.34 [pixels] > Standard deviation: 32.78 [pixels]