如何去除水平线和垂直线
How to remove horizontal and vertical lines
我需要删除二值图像中的水平线和垂直线。有什么方法可以过滤这些行吗? 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
你可以先找到横线和竖线。因为,边缘图也将是二进制的,因此您可以在图像之间执行逻辑减法运算。要查找垂直线,您可以使用(在 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);
使用 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);
输出:
如果您的所有图像在水平线和垂直线接触边界的地方都相同,只需调用 imclearborder
即可。 imclearborder
删除所有接触图像边界的对象像素。您需要反转图像,使字符为白色,背景为深色,然后再反转回来,但我认为这不是问题。然而,为了确保 none 的实际字符被删除,因为它们也可能接触到边框,谨慎的做法是用单个像素厚度人为地填充图像的顶部边框,清除边框,然后重新种植。
im = imread('http://i.stack.imgur.com/L1hUa.jpg'); %// Read image directly from Whosebug
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
我们得到这个:
我需要删除二值图像中的水平线和垂直线。有什么方法可以过滤这些行吗? 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
你可以先找到横线和竖线。因为,边缘图也将是二进制的,因此您可以在图像之间执行逻辑减法运算。要查找垂直线,您可以使用(在 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);
使用 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);
输出:
如果您的所有图像在水平线和垂直线接触边界的地方都相同,只需调用 imclearborder
即可。 imclearborder
删除所有接触图像边界的对象像素。您需要反转图像,使字符为白色,背景为深色,然后再反转回来,但我认为这不是问题。然而,为了确保 none 的实际字符被删除,因为它们也可能接触到边框,谨慎的做法是用单个像素厚度人为地填充图像的顶部边框,清除边框,然后重新种植。
im = imread('http://i.stack.imgur.com/L1hUa.jpg'); %// Read image directly from Whosebug
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
我们得到这个: