How to remove horizontal and vertical lines
I need to remove horizontal and vertical lines in a binary image. Is there a way to filter these lines? bwareaopen()
is not a good method to remove these lines, and Dilation and Erosion are not suitable for these cases. Does anyone know a solution?
Image example:
EDIT: (more example images added:
http://s1.upload7.ir/downloads/pPqTDnmsmjHUGTEpbwnksf3uUkzncDwr/example%202.png
original image file:
https://www.dropbox.com/sh/tamcdqk244ktoyp/AAAuxkmYgBkB8erNS9SajkGVa?dl=0
www.directexe.com/9cg/pics.rar
source to share
Use regionprops
and remove areas with high eccentricity (that is, the area is long and thin) and an orientation of about 0 or about 90 degrees (areas are vertical or horizontal).
Code:
img = im2double(rgb2gray(imread('removelines.jpg'))); mask = ~im2bw(img); rp = regionprops(mask, 'PixelIdxList', 'Eccentricity', 'Orientation'); % Get high eccentricity and orientations at 90 and 0 degrees rp = rp([rp.Eccentricity] > 0.95 & (abs([rp.Orientation]) < 2 | abs([rp.Orientation]) > 88)); mask(vertcat(rp.PixelIdxList)) = false; imshow(mask);
Output:
source to share
If all of your images match when the horizontal and vertical lines touch the border, a simple call imclearborder
would be Show Focus. imclearborder
removes any pixels from objects that touch the borders of the image. You will need to invert the image so that the characters are white and the background is dark and then go back again, but I assume this is not a problem. However, to be sure that none of the actual characters get deleted, as they might touch the border as well, it might be prudent to artificially overlay the top border of the image with one pixel thickness, clear the border, and then restore.
im = imread('http://i.stack.imgur.com/L1hUa.jpg'); %// Read image directly from StackOverflow
im = ~im2bw(im); %// Convert to black and white and invert
im_pad = zeros(size(im,1)+1, size(im,2)) == 1; %// Pad the image too with a single pixel border
im_pad(2:end,:) = im;
out = ~imclearborder(im_pad); %// Clear border pixels then reinvert
out = out(2:end,:); %// Crop out padded pixels
imshow(out); %// Show image
We get the following:
source to share
You can find horizontal and vertical lines first. Since the edge map will also be binary, so you can perform logical subtraction between images. To find vertical lines you can use (in MATLAB)
BW = edge(I,'sobel','vertical');
For horizontal lines, you can use
% Generate horizontal edge emphasis kernel h = fspecial('sobel'); % invert kernel to detect vertical edges h = h'; J = imfilter(I,h);
source to share