I am attempting to delete colored lines (specifically a yellow and blue line) within a series of images in Matlab. An example image can be found here:
I am able to segment out the blue line segments using basic thresholding. I am also able to segment out the bright yellow circles within the yellow line segment using thresholding. Finally, I am working on removing the remaining elements of the line segment using a hough transform w/ the houghlines function and a mask.
Is there a more elegant way to perform this, or am I stuck employing this combination of methods?
Thanks
Edit: I discovered that the hough transform is only removing single pixels from my image and not the entire yellow line. I was contemplating dilating around the detected pixels and checking for similarity, but I'm worried that the yellow line is too similar to the background colors (it's position could change such that it is not fully tracking the dark background it happens to be over now). Any suggestions would be greatly appreciated.
%% 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
It turns out that the answer involved converting the image into the Lab colorspace and performing treshholding. This segmented out the lines with minimal loss in the rest of the image. The code is below:
% 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;