Selecting a string using hough transform
Problem: Find unwanted string in image using Hough transform.
I did the following:
- Apply directional filter to analyze 12 different directions rotated about 15 ° one after another.
- Apply threshold to get 12 binary images.
Now I need to select any of the two images marked in yellow. Coz, the lines in these two images are the most prominent.
I have tried the following code. It doesn't seem to work.
MATLAB code
% Read 12 images into workspace.
input_images = {imread('1.png'),imread('2.png'),imread('3.png'),...
imread('4.png'),imread('5.png'),imread('6.png'),...
imread('7.png'),imread('8.png'),imread('9.png'),...
imread('10.png'),imread('11.png'),imread('12.png')};
longest_line = struct('point1',[0 0], 'point2',[0 0], 'theta', 0, 'rho', 0);
for n=1:12
%Create a binary image.
binary_image = edge(input_images{n},'canny');
%Create the Hough transform using the binary image.
[H,T,R] = hough(binary_image);
%Find peaks in the Hough transform of the image.
P = houghpeaks(H,3,'threshold',ceil(0.3*max(H(:))));
%Find lines
hough_lines = houghlines(binary_image,T,R,P,'FillGap',5,'MinLength',7);
longest_line = FindTheLongestLine(hough_lines, longest_line);
end
% Highlight the longest line segment by coloring it cyan.
plot(longest_line.point1, longest_line.point2,'LineWidth',2,'Color','cyan');
...
Corresponding source code
function longest_line = FindTheLongestLine( hough_lines , old_longest_line)
%FINDTHELONGESTLINE Summary of this function goes here
% Detailed explanation goes here
longest_line = struct('point1',[0 0] ,'point2',[0 0],'theta', 0, 'rho', 0);
max_len = 0;
N = length(hough_lines);
for i = 1:N
% Determine the endpoints of the longest line segment
len = LenthOfLine(hough_lines(i));
if ( len > max_len)
max_len = len;
longest_line = hough_lines(i);
end
end
old_len = LenthOfLine(old_longest_line);
new_len = LenthOfLine(longest_line);
if(old_len > new_len)
longest_line = old_longest_line;
end
end
function length = LenthOfLine( linex )
%LENTHOFLINE Summary of this function goes here
% Detailed explanation goes here
length = norm(linex.point1 - linex.point2);
end
Image testing
Here are 12 images, drive.google.com/open?id=0B-2FDw63ZNTnRnEzYlNyS0V4YVE
source to share
The problem with your code is the property FillGap
houghlines
. You have to allow large spaces in the returned strings, because the string you are looking for does not have to be contiguous, for example. 500:
hough_lines = houghlines(binary_image,T,R,P,'FillGap',500,'MinLength',7);
This finds the largest row in image 7 at will.
Visualization
To build the found string on top of the image, you can use the following code:
figure
imshow(input_images{7});
hold on
% Highlight the longest line segment by coloring it cyan.
plot([longest_line.point1(1) longest_line.point2(1)], [longest_line.point1(2) longest_line.point2(2)],'LineWidth',2,'Color','cyan');
Finding the maximum peak in the Hough transform
Alternatively, you might consider choosing the string that matches the largest Hough conversion value instead of the longest string. This can be done by choosing longest_line
as follows:
longest_line = ...
largest_H = 0; % init value
for n=1:12
binary_image = edge(input_images{n},'canny');
[H,T,R] = hough(binary_image);
P = houghpeaks(H,1,'threshold',ceil(0.3*max(H(:))));
hough_lines = houghlines(binary_image,T,R,P,'FillGap',500,'MinLength',7);
if (largest_H < H(P(1, 1), P(1, 2)))
largest_H = H(P(1, 1), P(1, 2));
longest_line = hough_lines(1);
longest_line.image = n;
end
end
This selects the next line in image 6, which is another valid result:
source to share
you can try changing the parameters of the Hough functions according to your specific problem, this is not an ideal solution, but it might be enough for you:
img = im2double(rgb2gray(imread('line.jpg')));
% edge image
BW = edge(img,'canny');
% relevant angles (degrees) interval for the line you want
thetaInterval = -80:-70;
% run hough transform and take single peak
[H,T,R] = hough(BW,'Theta',thetaInterval);
npeaks = 1;
P = houghpeaks(H,npeaks);
% generate lines
minLen = 150; % you want the long line which is ~250 pixels long
% merge smaller lines (same direction) within gaps of 30 pixels
fillGap = 30;
lines = houghlines(BW,T,R,P,'FillGap',fillGap,'MinLength',minLen );
% plot
imshow(img);
hold on
xy = [lines.point1; lines.point2];
plot(xy(:,1),xy(:,2),'g','LineWidth',2);
source to share