Reputation: 51
I need to remove horizontal and vertical lines in a binary image. Is there any method for filtering these lines? bwareaopen()
is not good method to remove these lines and also Dilation and Erosion are not good for these cases.
Does any one know a solution?
Example image:
EDIT:(added more example images:
http://s1.upload7.ir/downloads/pPqTDnmsmjHUGTEpbwnksf3uUkzncDwr/example%202.png
source file of images:
https://www.dropbox.com/sh/tamcdqk244ktoyp/AAAuxkmYgBkB8erNS9SajkGVa?dl=0
www.directexe.com/9cg/pics.rar
Upvotes: 3
Views: 3057
Reputation: 104514
If all of your images are the same where the horizontal and vertical lines are touching the border, a simple call to imclearborder
will do the trick. imclearborder
removes any object pixels that are touching the borders of the image. You'll need to invert the image so that the characters are white and the background is dark, then reinvert back, but I'm assuming that isn't an issue. However, to be sure that none of the actual characters get removed because they may also be touching the border, it may be prudent to artificially pad the top border of the image with a single pixel thickness, clear the border, then recrop.
im = imread('https://i.sstatic.net/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 this:
Upvotes: 3
Reputation: 4650
Use regionprops
and remove regions with high eccentricity (meaning the region is long and thin) and orientation near 0 or near 90 degrees (regions which 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:
Upvotes: 6
Reputation: 656
You can firstly find the horizontal and vertical lines. Since, the edge map will also be binary so you can perform a logical subtraction operation in between the 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);
Upvotes: 1