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

Этот пример показывает, как идентифицировать различные цвета в матрице путем анализа L*a*b* цветовое пространство. Изображение матрицы было получено с помощью Image Acquisition Toolbox™.

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

Читайте в изображении fabric.png, которое является изображением красочной матрицы. Вместо того, чтобы использовать fabric.png, можно получить изображение с помощью следующих функций в Image Acquisition Toolbox.

% Access a Matrox(R) frame grabber attached to a Pulnix TMC-9700 camera, and
% acquire data using an NTSC format.  
% vidobj = videoinput('matrox',1,'M_NTSC_RGB');

% Open a live preview window.  Point camera onto a piece of colorful fabric.
% preview(vidobj);

% Capture one frame of data.
% fabric = getsnapshot(vidobj);
% imwrite(fabric,'fabric.png','png');

% Delete and clear associated variables.
% delete(vidobj)
% clear vidobj;

fabric = imread('fabric.png');
imshow(fabric)
title('Fabric')

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

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

L*a*b* цветовое пространство выведен от CIE трехцветные значения XYZ. L*a*b* пробел состоит из яркости 'L*' или слой яркости, слой цветности '*' указание, где цвет падает вдоль красно-зеленой оси и слоя цветности 'b*' указание, где цвет падает вдоль сине-желтой оси.

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

Чтобы упростить этот пример, загрузите координаты области, которые хранятся в MAT-файле.

load regioncoordinates;

nColors = 6;
sample_regions = false([size(fabric,1) size(fabric,2) nColors]);

for count = 1:nColors
  sample_regions(:,:,count) = roipoly(fabric,region_coordinates(:,1,count), ...
                                      region_coordinates(:,2,count));
end

imshow(sample_regions(:,:,2))
title('Sample Region for Red')

Преобразуйте свое изображение RGB матрицы в L*a*b* изображение с помощью rgb2lab.

lab_fabric = rgb2lab(fabric);

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

a = lab_fabric(:,:,2);
b = lab_fabric(:,:,3);
color_markers = zeros([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

Например, средний цвет красной демонстрационной области в 'a*b*' пробел

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

Шаг 3: классифицируйте каждый пиксель, использующий самое близкое соседнее правило

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

Создайте массив, который содержит ваши цветные метки, т.е. 0 = фон, 1 = красный, 2 = зеленый, 3 = фиолетовый, 4 = пурпурный, и 5 = желтый.

color_labels = 0:nColors-1;

Инициализируйте матрицы, которые будут использоваться в самой близкой соседней классификации.

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

Выполните классификацию

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;

Шаг 4: отобразите результаты самой близкой соседней классификации

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

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 

Отобразите пять сегментированных цветов как монтаж. Также отобразите фоновые пиксели в изображении, которые не классифицируются как цвет.

montage({segmented_images(:,:,:,2),segmented_images(:,:,:,3) ...
    segmented_images(:,:,:,4),segmented_images(:,:,:,5) ...
    segmented_images(:,:,:,6),segmented_images(:,:,:,1)});
title("Montage of Red, Green, Purple, Magenta, and Yellow Objects, and Background")

Шаг 5: отобразитесь '*' и 'b*' значения маркированных цветов

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

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

figure
for count = 1:nColors
  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');