이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.
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* 컬러스페이스로 계산하기
영상에서 6가지 주요 색 즉, 배경색, 빨간색, 녹색, 자주색, 노란색, 자홍색을 볼 수 있습니다. 이러한 색을 눈으로 얼마나 쉽게 구별할 수 있는지 보십시오. L*a*b* 컬러스페이스(CIELAB 또는 CIE L*a*b*라고도 함)를 사용하면 이러한 시각적 차이를 수량화할 수 있습니다.
L*a*b* 컬러스페이스는 CIE XYZ 3자극값에서 파생됩니다. 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')
rgb2lab
를 사용하여 직물 RGB 영상을 L*a*b* 영상으로 변환합니다.
lab_fabric = rgb2lab(fabric);
roipoly
를 사용하여 추출한 각 영역의 평균 'a*' 및 'b*' 값을 계산합니다. 이러한 값은 '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단계: 최근접이웃 규칙을 사용하여 각 픽셀 분류하기
이제 각 색 마커는 '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;
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
5개의 분할된 색을 몽타주 형태로 표시합니다. 영상에서 색으로 분류되지 않은 배경 픽셀도 표시합니다.
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단계: 레이블이 지정된 색의 'a*' 값과 'b*' 값 표시하기
별도의 색으로 분류된 픽셀의 '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');