Colour Segmentation by l*a*b

2019-07-21 03:11发布

问题:

I'm using the code on the MatLab website, "Color-Based Segmentation Using the Lab* Color Space": http://www.mathworks.com/help/images/examples/color-based-segmentation-using-the-l-a-b-color-space.html

So I'm trying to select some areas myself instead of using the "load region_coordinates", using roipoly(fabric), but i get stuck. How do I save coordinates of the polygon I just drew? I'm actually following advice from lennon310 at Solution II, bottom of page: A few questions about color segmentation with L*a*b*

I'm not sure when to save region_coordinates and do size(region_coordinates,1)

I made the following changes (Step 1):

1) Removed "load region_coordinates"

2) Added "region_coordinates = roipoly(fabric);"

Here's the code:

` %% Step 1

fabric = imread(file);

figure(1);                                                                   %Create figure window. "If h is not the handle and is not the Number property value of an existing figure, but is an integer, then figure(h) creates a figure object and assigns its Number property the value h."
imshow(fabric)
title('fabric')



%load regioncoordinates; % 6 marices(?) labelled val(:,:,1-6), 5x2 (row x column)
region_coordinates = roipoly(fabric);

nColors = 6;
sample_regions = false([size(fabric,1) size(fabric,2) nColors]); %Initializing an Image Dimension, 3x3 (:,:,:) to zero? Zeros() for arrays only I guess.
                        %Size one is column, size two is row?
for count = 1:nColors
  sample_regions(:,:,count) = roipoly(fabric,region_coordinates(:,1,count),region_coordinates(:,2,count));

end

figure, imshow(sample_regions(:,:,2)),title('sample region for red'); 

%%Step 2

% Convert your fabric RGB image into an L*a*b* image using rgb2lab .

lab_fabric = rgb2lab(fabric);


%Calculate the mean a* and b* value for each area that you extracted with roipoly. These values serve as your color markers in a*b* space.

a = lab_fabric(:,:,2);
b = lab_fabric(:,:,3);
color_markers = zeros([nColors, 2]);%... I think this is initializing a 6x2 blank(0) array for colour storage. 6 for colours, 2 for a&b colourspace.

for count = 1:nColors
  color_markers(count,1) = mean2(a(sample_regions(:,:,count))); %Label for repmat, Marker for 
  color_markers(count,2) = mean2(b(sample_regions(:,:,count)));
end

%For example, the average color of the red sample region in a*b* space is

fprintf('[%0.3f,%0.3f] \n',color_markers(2,1),color_markers(2,2));

%% Step 3: Classify Each Pixel Using the Nearest Neighbor Rule %

color_labels = 0:nColors-1;

% Initialize matrices to be used in the nearest neighbor classification.

a = double(a);
b = double(b);
distance = zeros([size(a), nColors]); 


%Perform classification, Elucidean Distance.

for count = 1:nColors
  distance(:,:,count) = ( (a - color_markers(count,1)).^2 + (b - color_markers(count,2)).^2 ).^0.5;
end

[~, label] = min(distance,[],3);
label = color_labels(label);
clear distance;

%% Step 4: Display Results of Nearest Neighbor Classification % % The label matrix contains a color label for each pixel in the fabric image. % Use the label matrix to separate objects in the original fabric image by color.

rgb_label = repmat(label,[1 1 3]);
segmented_images = zeros([size(fabric), nColors],'uint8');

for count = 1:nColors
  color = fabric;
  color(rgb_label ~= color_labels(count)) = 0;
  segmented_images(:,:,:,count) = color;
end

%figure, imshow(segmented_images(:,:,:,1)), title('Background of Fabric');
%Looks different somehow.
figure, imshow(segmented_images(:,:,:,2)), title('red objects');

figure, imshow(segmented_images(:,:,:,3)), title('green objects');

figure, imshow(segmented_images(:,:,:,4)), title('purple objects');

figure, imshow(segmented_images(:,:,:,5)), title('magenta objects');

figure, imshow(segmented_images(:,:,:,6)), title('yellow objects');



`

回答1:

You can retrieve the coordinates of the polygon using output arguments in the call to roipoly. You can then get a binary mask of the polygon, as well as vertices coordinates if you want.

Simple example demonstrating:

clear
clc
close all

A = imread('cameraman.tif');

figure;
imshow(A)

%// The vertices of the polygon are stored in xi and yi;
%// PolyMask is a binary image where pixels == 1 are white.
[polyMask, xi, yi] = roipoly(A);

This looks like this:

And if you wish to see the vertices with the binary mask:

%// display polymask
imshow(polyMask)
hold on

%// Highlight vertices in red
scatter(xi,yi,60,'r')
hold off

Which gives the following:

So to summarize:

1) The polygon's vertices are stored in xi and yi.

2) You can plot the binaryMask of the polygon using imshow(polyMask).

3) If you need the coordinates of the white pixels, you can use something like this:

[row_white,col_white] = find(polyMask == 1);

You're then good to go. Hope that helps!