我需要删除二进制图像中的水平和垂直线。有没有过滤这些线的方法? bwareaopen()
不是去除这些线的好方法,而且膨胀和侵蚀对这些情况也不好。
有人知道解决方案吗?
示例图片:
编辑:(添加了更多示例图片:
http://s1.upload7.ir/downloads/pPqTDnmsmjHUGTEpbwnksf3uUkzncDwr/example%202.png
图片的源文件:
https://www.dropbox.com/sh/tamcdqk244ktoyp/AAAuxkmYgBkB8erNS9SajkGVa?dl=0
www.directexe.com/9cg/pics.rar
答案 0 :(得分:6)
使用regionprops
并移除具有高偏心率的区域(意味着区域长而细)并且方向接近0或接近90度(垂直或水平的区域)。
代码:
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);
输出:
答案 1 :(得分:3)
如果所有图像都是水平线和垂直线接触边框的图像,只需调用imclearborder
即可。 imclearborder
删除任何触及图像边框的对象像素。您需要反转图像,使字符为白色,背景为暗,然后重新转回,但我认为这不是问题。但是,为了确保没有任何实际字符被删除,因为它们也可能触摸边框,因此用单个像素厚度人工填充图像的顶部边框,清除边框然后重新编写可能是谨慎的。
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
我们得到了这个:
答案 2 :(得分:1)
您可以先找到水平线和垂直线。因为,边缘图也将是二进制的,因此您可以在图像之间执行逻辑减法运算。要查找垂直线,可以使用(在MATLAB中)
BW = edge(I,'sobel','vertical');
对于水平线,您可以使用
% Generate horizontal edge emphasis kernel
h = fspecial('sobel');
% invert kernel to detect vertical edges
h = h';
J = imfilter(I,h);