В этом примере показано, как идентифицировать различные цвета в ткани путем анализа L * a * b * colorspace.
Читайте в fabric.png
изображение, представляющее собой изображение красочной ткани.
fabric = imread('fabric.png'); imshow(fabric) title('Fabric')
На изображении можно увидеть шесть основных цветов: цвет фона, красный, зеленый, фиолетовый, желтый и пурпурный. Заметьте, как легко вы можете визуально отличить эти цвета друг от друга. Пространство цветов L * a * b * (также известное как CIELAB или CIE L * a * b *) позволяет вам количественно оценить эти визуальные различия.
Цветовое пространство L * a * b * определяется из значений CIE XYZ tristimulus. Пространство L * a * b * состоит из слоя светимости 'L *' или яркости, слоя цветности 'a *', указывающего, где цвет падает вдоль красно-зеленой оси, и слоя цветности '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);
Вычислите среднее значение 'a *' и '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]
Каждый цветовой маркер теперь имеет значение 'a *' и '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;
Матрица меток содержит цветовую метку для каждого пикселя в изображении ткани. Используйте матрицу меток, чтобы разделить объекты в исходном изображении ткани по цвету.
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")
Можно увидеть, как хорошо классификация ближайших соседей разделила различные цветовые населения путем построения графиков значений 'a *' и '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');