# Line tracing folowing a path of an almost connected components

say we have a binary image like the one in below

i would like to extract each black line, even if it's not almost connected

i have marked here in red, example of lines that correspond to those to be extracted

**the purpose here is to extract lines a handwritten text ! **

any suggestions !! Thanks

• Please post an image without the red lines, so that other people will have a change to play around with it Jan 1 '15 at 15:31
• Is the first and second image a processing that you did for the third? Jan 1 '15 at 18:58

## 2 Answers

Here is a possible solution:

• Use FFT2 to find angle of text and approximate spaces between lines
• Rotate the image to be at 0 angle
• Sum the image column-wise
• Find threshold that splits lines of text from non text lines
• Show lines on rotated image.

It can be improved by finding a more complex curve (rather than line).

Here are the results:

Original

After rotation

Sum of rotated image column-wise

Final results

And the code is:

%% 1) Read image
im = imread('http://i.stack.imgur.com/zbHTp.jpg');
im = im(:,:,2);
im = double(im < 100);
im = padarray(im,[40 0]);
figure();imshow(im);

%% 2) Find approximate line spacing
F = fftshift(fft2(im));
% figure;imagesc(log(abs(fftshift(fft2(im)))));
[~,iMax] = max(F(:));
[r1,c1] = ind2sub(size(F),iMax);
F(iMax) = 0;
[~,iMax2] = max(F(:));
[r2,c2] = ind2sub(size(F),iMax2);
lineSpaceY = size(im,1)/ abs(r2-r1);
lineSpaceX = size(im,2)/ abs(c2-c1);
angleDeg = abs(90-rad2deg( atan2(lineSpaceX,lineSpaceY)));
imr = imrotate(im,angleDeg);
figure;imshow(imr);

%% 3) Take a look at 1D signal
S = mean(imr,2);
isText = S > max(S)/2;
isText = imclose(isText,strel('line',lineSpaceY/10,90));
% figure(); plot(isText,'o-');
rp = regionprops(isText,'Centroid');
centerY = cat(1,rp.Centroid);
centerY = centerY(:,2);

%% 4) Show final results
figure();imshow(imr);
for i=1:numel(centerY);
hold on;
plot( [0,size(im,2)],[centerY(i) centerY(i)],'g','LineWidth',2);
end


First of all, if the lines aren't connected, apply a morphological opening operation to make them so (see morphologyEx in OpenCV).

Now, assuming you have a connected black region, you could apply iterative thining to obtain the skeleton. Or refer to already available ideas such as this one or this one.