1

Я пытаюсь удалить цветные линии (в частности, желтую и синюю линию) в пределах серии изображений в Matlab. Пример изображения можно найти здесь:Удаление цветных линий в Matlab

enter image description here

Я сегментировать из синих отрезков, используя базовую пороговую. Я также могу сегментировать яркие желтые круги в желтом сегменте линии с использованием пороговых значений. Наконец, я работаю над удалением оставшихся элементов сегмента линии с использованием преобразования hough с функцией houghlines и маски.

Есть ли более элегантный способ выполнить это, или я застрял, используя эту комбинацию методов?

Благодаря

Edit: я обнаружил, что поджилки преобразования только удаление отдельных пикселей из моего изображения, а не вся желтая линия. Я размышлял о расширении вокруг обнаруженных пикселей и проверке на сходство, но я обеспокоен тем, что желтая линия слишком похожа на цвета фона (позиция может измениться так, что она не полностью отслеживает темный фон, в котором это происходит сейчас). Любые предложения будут ценны.

%% This block was intended to deal with another data 
set this function has to analyze, but it actually ended up removing my 
yellow circles as well, making a further threshold step unnecessary so far 

% Converts to a binary image containing almost exclusively lines and crosshairs 
mask = im2bw(rgb_img, 0.8); 

% Invert mask 
mask = ~mask; 

% Remove detected lines and crosshairs by setting to 0 
rgb_img(repmat(~mask, [1, 1, 3])) = 0; 

%% Removes blue targetting lines if present 

% Define thresholds for RGB channel 3 based on histogram settings to remove 
% blue lines 

channel3Min = 0.000; 
channel3Max = 0.478; 

% Create mask based on chosen histogram thresholds 
noBlue = (rgb_img(:,:,3) >= channel3Min) & (rgb_img(:,:,3) <= channel3Max); 

% Set background pixels where noBlue is false to zero. 
rgb_img(repmat(~noBlue,[1 1 3])) = 0; 

%% Removes any other targetting lines if present 

imageGreyed = rgb2gray(rgb_img); 

% Performs canny edge detection 
BW = edge(imageGreyed, 'canny'); 

% Computes the hough transform 
[H,theta,rho] = hough(BW); 

% Finds the peaks in the hough matrix 
P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:)))); 

% Finds any large lines present in the image 
lines = houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',100); 

colEnd = []; 
rowEnd = []; 

for i = 1:length(lines) 

    % Extracts line start and end points from houghlines output 

    pointHold = lines(i).point1; 
    colEnd = [colEnd pointHold(1)]; 
    rowEnd = [rowEnd pointHold(2)]; 

    pointHold = lines(i).point2; 
    colEnd = [colEnd pointHold(1)]; 
    rowEnd = [rowEnd pointHold(2)]; 

    % Creates a line segment from the line endpoints using a simple linear regression 
    fit = polyfit(colEnd, rowEnd, 1); 

    % Creates index of "x" (column) values to be fed into regression 
    colIndex = (colEnd(1):colEnd(2)); 

    rowIndex = []; 

    % Obtains "y" (row) pixel values from regression 

    for i = colIndex 

     rowHold = fit(1) * i + fit(2); 
     rowIndex = [rowIndex rowHold]; 

    end 

    % Round regression output 
    rowIndex = round(rowIndex); 

    % Assemble coordinate matrix 
    lineCoordinates = [colIndex; rowIndex]'; 

    rgbDim = size(rgb_img); 

    % Create mask based on input image size 
    yellowMask = ones(rgbDim(1), rgbDim(2)); 

    for i = 1:length(rowIndex) 

     yellowMask(rowIndex(i), colIndex(i)) = 0; 

    end 

    % Remove the lines found by hough transform 
    rgb_img(repmat(~yellowMask,[1 1 3])) = 0; 

end 

end 
+1

Можем ли мы увидеть код, который вы написали, чтобы решить эту проблему? – rayryeng

+0

Добавлен код и обновление – Hosty

ответ

0

Оказывается, что ответ включал преобразование изображения в цветовое пространство Lи выполнение трэшхолдинга. Это сегментировало линии с минимальной потерей в остальной части изображения. Код ниже:

% Convert RGB image to L*a*b color space for thresholding 
    rgb_img = im2double(rgb_img); 
    cform = makecform('srgb2lab', 'AdaptedWhitePoint', whitepoint('D65')); 
    I = applycform(rgb_img,cform); 

    % Define thresholds for channel 2 based on histogram settings 
    channel2Min = -1.970; 
    channel2Max = 48.061; 

    % Create mask based on chosen histogram threshold 
    BW = (I(:,:,2) <= channel2Min) | (I(:,:,2) >= channel2Max); 

    % Determines the eccentricity for regions of pixels; basically how line-like 
    % (vals close to 1) or circular (vals close to 0) the region is 
    rp = regionprops(BW, 'PixelIdxList', 'Eccentricity'); 

    % Selects for regions which are not line segments (areas which 
    % may have been incorrectly thresholded out with the crosshairs) 
    rp = rp([rp.Eccentricity] < 0.99); 

    % Removes the non-line segment regions from the mask 
    BW(vertcat(rp.PixelIdxList)) = false; 

    % Set background pixels where BW is false to zero. 
    rgb_img(repmat(BW,[1 1 3])) = 0; 
0

Я кратко протестировали пример, приведенный на http://de.mathworks.com/help/images/examples/color-based-segmentation-using-k-means-clustering.html?prodcode=IP&language=en

используя изображение, которое:

he = imread('HlQVN.jpg'); 
imshow(he) 
cform = makecform('srgb2lab'); 
lab_he = applycform(he,cform); 
ab = double(lab_he(:,:,2:3)); 
nrows = size(ab,1); 
ncols = size(ab,2); 
ab = reshape(ab,nrows*ncols,2); 
nColors = 3; 
% repeat the clustering 3 times to avoid local minima 
[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ... 
             'Replicates',3); 
pixel_labels = reshape(cluster_idx,nrows,ncols); 
segmented_images = cell(1,3); 
rgb_label = repmat(pixel_labels,[1 1 3]); 

for k = 1:nColors 
    color = he; 
    color(rgb_label ~= k) = 0; 
    segmented_images{k} = color; 
end 
imshow(segmented_images{1}), title('objects in cluster 1'); 

это уже довольно хорошо идентифицирует синюю линию.

+0

Хотя это было чрезвычайно интересно и информативно, оказалось, что просто преобразование в цветовое пространство Lab было прорывом, в котором я нуждался. Я легко мог все порочить. Благодаря! – Hosty

+0

@Hosty Я рад, что это помогло, удачи – horseshoe

0

Это сообщение не войдет в проблему обработки изображений, а скорее сосредоточится на реализации и предложит способы улучшения существующего кода. Теперь код имеет polyfit расчет на каждой итерации цикла, который я не уверен, мог быть векторизован. Итак, скорее давайте попробуем векторизовать остальную часть кодов внутри цикла и, надеюсь, это приведет к некоторому ускорению для общего кода. Изменения, которые я хотел бы предложить, находятся на двух шагах внутри самого внутреннего цикла.

1) Заменить -

rowIndex=[] 
for i = colIndex 
    rowHold = fit(1) * i + fit(2) 
    rowIndex = [rowIndex rowHold];  
end 

с -

rowIndex = fit(1)*colIndex + fit(2) 

2) Заменить -

yellowMask = ones(rgbDim(1), rgbDim(2)); 
for i = 1:length(rowIndex) 
    yellowMask(rowIndex(i), colIndex(i)) = 0; 
end 
rgb_img(repmat(~yellowMask,[1 1 3])) = 0; 

с -

idx1 = (colIndex-1)*rgbDim(1) + rowIndex 
rgb_img(bsxfun(@plus,idx1(:),[0:rgbDim(3)-1]*rgbDim(1)*rgbDim(2))) = 0; 
Смежные вопросы