Цветовая сегментация ткани с использованием цветового пространства L * a * b

Этот пример показывает, как получить одну систему координат изображения кусочка красочной ткани. Различные цвета в ткани идентифицируются с помощью цветового пространства L * a * b.

Этот пример требует использования Image Processing Toolbox™.

Шаг 1: Получить изображение

% Create a video input object to access the image acquisition device.
vid = videoinput('matrox', 1, 'M_NTSC');

% Capture one frame of data.
fabric = getsnapshot(vid);
figure(1)
imshow(fabric)
title('original image');

% Determine the image resolution.
imageRes = vid.VideoResolution;
imageWidth = imageRes(1);
imageHeight = imageRes(2);

% Once the video input object is no longer needed, delete
% it and clear it from the workspace.
delete(vid)
clear vid

Шаг 2: Вычислите выборки цветов в L * a * b цветовом пространстве для каждой области

Подсчитайте количество основных цветов, видимых на изображении. Заметьте, как легко вы можете визуально отличить эти цвета друг от друга. Цветовое пространство L * a * b (также известное как CIELAB или CIE L * a * b) позволяет вам количественно определить эти визуальные различия.

Цветовое пространство L * a * b определяется из значений CIE XYZ tristimulus. Пространство L * a * b состоит из слоя светимости ('L') или яркости, слоя цветности 'a', указывающего, где цвет падает вдоль красно-зеленой оси, и слоя цветности 'b', указывающего, где цвет падает вдоль сине-желтой оси.

Ваш подход состоит в том, чтобы выбрать небольшую область выборки для каждого цвета и вычислить средний цвет каждой области выборки в пространстве 'a * b'. Вы будете использовать эти маркеры цвета для классификации каждого пикселя.

% Initialize storage for each sample region.
colorNames = { 'red','green','purple','blue','yellow' };
nColors = length(colorNames);
sample_regions = false([imageHeight imageWidth nColors]);

% Select each sample region.
f = figure;
for count = 1:nColors
    f.Name = ['Select sample region for ' colorNames{count}];
    sample_regions(:,:,count) = roipoly(fabric);
end
close(f);

% Display a sample region.
imshow(sample_regions(:,:,1))
title(['sample region for ' colorNames{1}]);

% Convert the fabric RGB image into an L*a*b image.
cform = makecform('srgb2lab');
lab_fabric = applycform(fabric,cform);

% Calculate the mean 'a' and 'b' value for each area extracted.
% These values serve as your color markers in 'a*b' space.
a = lab_fabric(:,:,2);
b = lab_fabric(:,:,3);
color_markers = repmat(0, [nColors, 2]);

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

% For example, the average color of the second sample region in 'a*b' space is:
disp( sprintf('[%0.3f,%0.3f]', color_markers(2,1), color_markers(2,2)) );
[105.956,147.867]

Шаг 3: Классификация каждого пикселя с помощью правила ближайшего соседа

Каждый цветовой маркер теперь имеет значение 'a' и 'b'. Можно классифицировать каждый пиксель в изображении, вычислив евклидово расстояние между этим пикселем и каждым цветовым маркером. Наименьшее расстояние подскажет, что пиксель наиболее близко совпадает с этим цветовым маркером. Для примера, если расстояние между пикселем и вторым маркером цвета является наименьшим, то пиксель будет помечен как этот цвет.

% Create an array that contains your color labels:
%     0 = background
%     1 = red
%     2 = green
%     3 = purple
%     4 = magenta
%     5 = yellow
color_labels = 0:(nColors-1);

% Initialize matrices to be used in the nearest neighbor classification.
a = double(a);
b = double(b);
distance = repmat(0,[size(a), nColors]);

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

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

Шаг 4: отображение результатов классификации ближайших соседей

Матрица меток содержит цветовую метку для каждого пикселя в изображении ткани. Используйте матрицу меток, чтобы разделить объекты в исходном изображении ткани по цвету.

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

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

imshow(segmented_images(:,:,:,1));
title([colorNames{1} ' objects'] );

imshow(segmented_images(:,:,:,2));
title([colorNames{2} ' objects'] );

imshow(segmented_images(:,:,:,3));
title([colorNames{3} ' objects'] );

imshow(segmented_images(:,:,:,4));
title([colorNames{4} ' objects'] );

imshow(segmented_images(:,:,:,5));
title([colorNames{5} ' objects'] );

Шаг 5: отображение значений 'a' и 'b' маркированных цветов

Можно увидеть, как хорошо классификация ближайших соседей разделила различные цветовые населения путем построения графиков значений 'a' и 'b' для пикселей, которые были классифицированы в отдельные цвета. В целях отображения пометьте каждую точку цветовой меткой.

purple = [119/255 73/255 152/255];
plot_labels = {'k', 'r', 'g', purple, 'b', 'y'};

figure
for count = 1:nColors
  h(count) = plot(a(label==count-1),b(label==count-1),'.','MarkerEdgeColor', ...
                  plot_labels{count}, 'MarkerFaceColor', plot_labels{count});
  hold on;
end

title('Scatterplot of the segmented pixels in ''a*b'' space');
xlabel('''a'' values');
ylabel('''b'' values');