因此,这基本上是非常简单的事情,如仅获取水平投影图并从中获取线条在图像上的位置。 但是问题在于所应用的阈值变化很大。 如果我保持安全水平,则可以提取正确的行数,而另一方面,可以提取不需要的结果。

例如,下面是图像:

在此处输入图片说明

及其水平投影:

在此处输入图片说明

这是我用来提取文本行的代码:

%complementing as text must be non zero and background should be 0
img_comp = imcomplement(img);

%calculate the horizontal projections and plot it to verify the threshold
horizontal_projections = sum(img_comp, 2);
plot(horizontal_projections)

%A very crude method of automatically detecting the threshold

proj_mean = mean(horizontal_projections);
lines = horizontal_projections > floor(proj_mean); 

% Find Rising and falling edges
d = diff(lines);
startingColumns = find(d>0);
endingColumns = find(d<0);

% Extract each line and save it in a cell
for lines_k = 1 : length(startingColumns)
  lines_extracted{lines_k} = img(startingColumns(lines_k):endingColumns(lines_k), :);
end

我想自动化阈值选择,但是遇到了麻烦,如果我使用代码中显示的阈值作为投影的均值,它会提取正确的9行,但是这些行会丢失很多数据,如下所示:

在此处输入图片说明

这是第二行,字母的扩展和降序已被截断。 使用一半的平均值或三分之一有效,但每个图像的平均值都不相同,并且根本无法实现自动化。

===============>>#1 票数:1 已采纳

如何转换为YCbCr颜色空间? 使用维基百科的转换公式。

img = im2double(imread('StackOverflow-Example.jpg'));
rp = img(:, :, 1) / 255 ;
bp = img(:, :, 2) / 255 ;
gp = img(:, :, 3) / 255 ;
kb = 0.114;
kr = 0.299;
y = kr * rp + (1 - kr - kb) * gp + kb * bp;
y = max(max(y))-y;
y = y ./ y;
surf(y,'EdgeColor','none','LineStyle','none')
view(0, -90)

维护信息看起来很不错。

编辑:

我想你要每一行

%% Load image and find intensity %%
img = im2double(imread('test.jpg')); % load image and convert to doubles to allow for calculations
rp = img(:, :, 1) / 255 ; % normalized red portion
bp = img(:, :, 2) / 255 ; % normalized blue portion
gp = img(:, :, 3) / 255 ; % normalized green portion
kb = 0.114; % blue constant from Wikipedia
kr = 0.299; % red constant from Wikipedia
x = kr * rp + (1 - kr - kb) * gp + kb * bp; % normalized intensity in image
x = max(max(x))-x; % removed background

y = x ./ x; % everything left is high

z = y;
z(isnan(y)) = 0; % turn nan's to zero
divisions = find(sum(z,2) > 5); % find all lines that have less than 5 pixels
divisions = [divisions(1); divisions(diff(divisions) > 10); size(z, 1)]; % find the line breaks

rows = cell(length(divisions), 1);

for i = 1:numel(rows)-1
    line = z(divisions(i):divisions(i+1), :); % grab line
    j = divisions(i) + find(sum(line,2) > 5) - 1; % remove the white space
    line = y(j, :);
    rows{i} = line; %store the line
end

rows(numel(rows)) = [];

%% plot each line %%
for i = 1:numel(rows) ; 
    figure(i) ; 
    surf(rows{i},'EdgeColor','none','LineStyle','none');
    view(0, -90) ;
end

%% plot entire page %%
figure(numel(rows) + 1)
surf(y,'EdgeColor','none','LineStyle','none') % plot of entire image
view(0, -90)

编辑:2015/05/18 15:45 GMT

剩下的强度值如下:

img = im2double(imread('test.jpg'));
rp = img(:, :, 1) / 255 ;
bp = img(:, :, 2) / 255 ;
gp = img(:, :, 3) / 255 ;
kb = 0.114;
kr = 0.299;
x = kr * rp + (1 - kr - kb) * gp + kb * bp;
x = max(max(x))-x;
xp = x;
xp(xp == min(min(xp))) = nan;

y = x ./ x;

z = y;
z(isnan(y)) = 0;
divisions = find(sum(z,2) > 5);
divisions = [divisions(1); divisions(diff(divisions) > 10); size(z, 1)];

rows = cell(length(divisions) - 1, 1);

for i = 1:numel(rows)
    line = z(divisions(i):divisions(i+1), :);
    j = divisions(i) + find(sum(line,2) > 5) - 1;
    line = xp(j, :);
    rows{i} = line;

    figure(i) ; 
    surf(rows{i},'EdgeColor','none','LineStyle','none');
    axis('equal')
    view(0, -90) ;
end

figure(numel(rows) + 1)
surf(xp,'EdgeColor','none','LineStyle','none')
axis('equal')
view(0, -90)

编辑2015-05-22 13:21 GMT

%Turn warning message off
warning('off', 'Images:initSize:adjustingMag');

%Read in image in int8
originalImg = imread('test.jpg');

%Convert to double
img = im2double(originalImg);

%Take R, G, & B components
rp = img(:, :, 1) ;
gp = img(:, :, 2) ;
bp = img(:, :, 3) ;

%Get intensity
kb = 0.114;
kr = 0.299;
yp = kr * rp + (1 - kr - kb) * gp + kb * bp;

%Flip to opposite of intensity
ypp = max(max(yp))-yp;

%Normalize flipped intensity
z = ypp ./ ypp;
z(isnan(z)) = 0;

%Find lines, this may need to be tuned
MaxPixelsPerLine = 5;
MinRowsPerLine = 10;
divisions = find(sum(z,2) > MaxPixelsPerLine);
divisions = [divisions(1); divisions(diff(divisions) > MinRowsPerLine); size(z, 1)];

%Preallocate for number of lines
colorRows = cell(length(divisions) - 1, 1);

for i = 1:numel(rows)
    %Extract the lines in RGB
    line = z(divisions(i):divisions(i+1), :);
    j = divisions(i) + find(sum(line,2) > 5) - 1;
    colorRows{i} = originalImg(j, :, :);

    %Print out the line
    figure(i) ;
    imshow(colorRows{i})
end

%Print out the oringinal image
figure(numel(rows) + 1)
imshow(originalImg)

%Turn the warning back on
warning('on', 'Images:initSize:adjustingMag');

===============>>#2 票数:1

简而言之: Graythresh(img)migth解决了您的问题

更长:

使用某些形态方法,您可以非常轻松地提取线条。 不过有一个小缺点:它们有些混乱。

载入您的图片

original = imread('o6WEN.jpg'); 

使其变成灰度

img=rgb2gray(original); .

定义一个大约textheight和“非常”长的矩形结构元素

se = strel('rectangle',[30 200]); 

用高帽过滤器过滤。 此后,具有大约textheight的长矩形形状将更加突出。

 img = imtophat(img,se);

调整对比度:

img = imadjust(img);

定义另一个结构元素,这次的行比textheight短:

se = strel('line',20,0);

扩大图片,以消除字母之间存在的间隙

img = imdilate(img,se);

使图像变黑并具有:

img=im2bw(img,graythresh(img));

使用regionprops将所有BoundingBoxes形成行

 stats=regionprops(img,'BoundingBox');
 figure, imshow(img)

现在,所有统计信息中的边界框都在统计中,令人不安的是。 也许可以使用BWlables或某种相关性来纠正此问题。 我只是看了BoundingBoxes的y坐标,并进行了相应的排序。

BoundingBoxes=struct2cell(stats);
BoundingBoxes=cell2mat(BoundingBoxes'); % making it into an array
[~,ind]=sort(BoundingBoxes(:,2)); % sorting it to y
BoundingBoxes=BoundingBoxes(ind,:); % apply the sorted vector 

 lineNr=8;
imshow(original(BoundingBoxes(2,lineNr):BoundingBoxes(2,lineNr)+BoundingBoxes(4,lineNr),BoundingBoxes(1,lineNr):BoundingBoxes(1,lineNr)+BoundingBoxes(3,lineNr)  ))

希望对你有用

  ask by StuckInPhD translate from so

未解决问题?本站智能推荐:

1回复

如何测量带标签的线段的面积?

我对图像进行了阈值处理,并使用label2rgb()使图像以不同的颜色显示不同的部分。 如何使用Matlab计算每种不同颜色的面积? 谢谢!
1回复

如何将线条的投影转换为任何可用的分割信息?

我一直在阅读有关Matlab中自动文本行识别的信息,尽管每篇论文都提到了许多高级方法可以做到这一点,但最简单的检测文本行的方法是通过水平投影。 因此,我决定自己尝试这种方法。 我对此很陌生,碰到了墙,我达到了一个不知如何进行的水平。 到目前为止,这是我实现的目标: 我正在尝试一个
1回复

Matlab:强制分水岭分割成特定数量的线段

为了避免Matlab中的分水岭算法过度分割,我想强制将算法分割为特定数量的段(在此处的示例中,算法自动分割为4,而我希望将其分割为2) 。 有没有一种通用的方法来定义允许的输出段数? 我当前正在使用的代码:
3回复

使用K均值聚类准确检测图像中的颜色区域

我在基于颜色的图像分割中使用K均值聚类。 我有一个具有3种颜色(黑色,白色和绿色)的2D图像。 这是图片, 我想让K均值产生3个簇,一个代表绿色区域,第二个代表白色区域,最后一个代表黑色区域。 这是我使用的代码, 但是我没有得到所需的结果。 我得到一个具有绿色区域
2回复

删除有机分子图中不需要的字符

我有这个图像: 我想删除图像中不构成有机分子结构一部分的所有部分。 所以在这个特定的图像中,我想删除Process A及其line below it的line below it 。 我尝试使用bwlabel来获取连接组件,但结构本身并不构成一个单独的组件。 因此,不可能通过该方法移
1回复

在Matlab中使用bwconncomp获取对象位置

为了进行分段,在matlab bwconncomp有一个函数。 它可以计算检测到的物体的数量。 当我访问PixelIdxList ,最大值为834。 那是什么834? 因为图像尺寸只有30x32。 以及如何使用PixelIdxList / bwconncomp信息获取对象
1回复

如何准确计算白块或小块的数量?

您好尝试使用此代码来消除噪点和模糊。 这是原始图片 这是经过处理的图像 问题是仍然有一些噪音残留,还有一些划分不明确,例如右上角的分区不见了。我想计算白块的数量,所以我会得到错误的答案。我是matlab和image的新手处理。
1回复

matlab - VideoReader帧未被准确解码

我在Matlab中处理视频,遇到麻烦。 我在Mac OS X 10.8.2(Mountain Lion)上使用Matlab R2012a。 我可以使用VideoReader加载视频并抓取一个框架,如下所示: 但是,我在Matlab中看到的是...... 而不是这个(在
2回复

如何忽略直方图中的某些值? 在Matlab中不使用NaN?

假设我有一个灰度图像S,并且我想忽略所有大于250的值,如何在不使用NaN的情况下做到这一点? 我不想使用NaN的原因是因为我希望从所得图像中获取统计信息,例如平均值等。
3回复

删除matlab子图中的间距

我应该如何删除这些图像之间的空白区域?我需要在没有任何空间的情况下组合所有这些图像。