【问题标题】:extract characters in sequence matlab在序列matlab中提取字符
【发布时间】:2023-04-10 13:38:01
【问题描述】:

我想提取一个序列中的字符。例如,给定这张图片:

这是我写的代码:

[L Ne]=bwlabel(BinaryImage);
stats=regionprops(L,'BoundingBox');
cc=vertcat(stats(:).BoundingBox);
aa=cc(:,3);
bb=cc(:,4);
hold on
figure
for n=1:size(stats,1)
    if (aa(n)/bb(n) >= 0.2 && aa(n)/bb(n)<= 1.25)
        [r,c] = find(L==n);
        n1=BinaryImage(min(r):max(r),min(c):max(c));
        imshow(~n1);
        pause(0.5)
    end
    hold off
end

我应该对正确的顺序进行哪些更改?

【问题讨论】:

  • 小注。 BinaryImage 应该反转,使文本为白色,背景为黑色。您的原始图像已翻转。
  • 是的,我总是在任何处理之前反转二进制图像。
  • 这在你的代码中并不明显,这就是我留下那个小注释的原因。

标签: image-processing extraction text-extraction


【解决方案1】:

regionprops 通过按 column-major 顺序查找 blob 进行操作。 regionprops 不按行优先顺序运行,这正是您要寻找的。列优先顺序源自 MATLAB 本身,因为以列优先顺序操作是本机行为。此外,您使用 find / bwlabel 的逻辑也以列优先格式运行,因此在尝试以行优先格式显示字符时,您必须牢记这两点。


因此,一种简单的方法是修改您的for 循环,以便您按行而不是按列访问结构。对于您的示例图像,字符的顺序描述如下:

 1   3   5
 2   4   6

您需要按以下顺序访问该结构:[1 3 5 2 4 6]。因此,您将更改您的 for 循环以访问这个新数组,您可以像这样创建这个新数组:

ind = [1:2:numel(stats) 2:2:numel(stats)];

完成此操作后,只需修改 for 循环以访问 ind 中的值。为了使您的代码完全可重现,我将直接从 StackOverflow 读取您的图像,并在文本为黑色时 invert 图像。文本需要为白色才能使 blob 分析成功:

%// Added
clear all; close all;
BinaryImage = ~im2bw(imread('http://s4.postimg.org/lmz6uukct/plate.jpg'));

[L Ne]=bwlabel(BinaryImage);
stats=regionprops(L,'BoundingBox');
cc=vertcat(stats(:).BoundingBox);
aa=cc(:,3);
bb=cc(:,4);
figure;

ind = [1:2:numel(stats) 2:2:numel(stats)]; %// Change
for n = ind %// Change
    if (aa(n)/bb(n) >= 0.2 && aa(n)/bb(n)<= 1.25)
        [r,c] = find(L==n);
        n1=BinaryImage(min(r):max(r),min(c):max(c));
        imshow(~n1);
        pause(0.5)
    end
end

警告

上面的代码假设只有两行字符。如果你有更多,那么很明显指定的索引将不起作用。

如果您希望它适用于多行,那么我要编写的这个逻辑假定文本是水平的而不是倾斜的。简而言之,您将循环直到用完结构,并且在循环开始时,您将搜索具有我们未处理的 blob 左上角的最小 (x,y) 坐标的 blob。一旦你找到这个,你搜索所有在这个源 y 坐标的某个阈值内的所有 y 坐标,你会在这些位置获取索引。你会重复这个直到你用完结构。

类似这样的:

thresh = 5; %// Declare tolerance

cc=vertcat(stats(:).BoundingBox);
topleft = cc(:,1:2);

ind = []; %// Initialize list of indices
processed = false(numel(stats),1); %// Figure out those blobs that have been processed
while any(~processed) %// While there is at least one blob to look at...
    %// Determine the blob that has the smallest y/row coordinate that's  
    %// unprocessed
    cc_proc = topleft(~processed,:);
    ys = min(cc_proc(:,2));

    %// Find all blobs along the same row that are +/-thresh rows from
    %// the source row
    loc = find(abs(topleft(:,2)-ys) <= thresh & ~processed);

    %// Add to list and mark them off
    ind = [ind; loc];
    processed(loc) = true;
end

ind = ind.'; %// Ensure it's a row

然后您将使用 ind 变量并将其与 for 循环一起使用,就像以前一样。

【讨论】:

  • 谢谢。有效。但我无法理解'ind = [1:2:numel(stats) 2:2:numel(stats)];'的含义.. numel 只是计算像素总数。它如何将列主要顺序更改为行主要顺序?
  • 仔细阅读帖子。如果你想要行主顺序,你必须以[1 3 5 2 4 6] 的顺序访问结构元素。该语句以这种方式生成索引。 1:2:numel(stats) 创建一个从 1 开始到您跳过 2 的元素的向量。2:2:numel(stats) 是一样的,但我们从 2 开始。尝试自己在 MATLAB 中查看向量,看看它确实有效。但是,让我更新帖子,以便您可以根据需要将其调整为尽可能多的字符。这篇文章目前假设有两行字符。
  • 当上行包含 3 个字母和下行包含 3 个数字时,它工作正常。但我有某些图像在下一行有 4 位数字。在这种情况下,它首先检测下线,然后检测上线。像s10.postimg.org/4ww3bjia1/plate.pngs10.postimg.org/4ww3bjia1/plate.png这样的图片
  • 我所有的图像只有 2 行。此外,有时它会随机检测(不是按顺序)。随机检测图像有一些方向。也许这会导致那个问题。
  • 感谢您的努力!
猜你喜欢
  • 2016-12-29
  • 2014-07-17
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 2018-11-12
  • 2018-12-06
  • 2021-01-22
相关资源
最近更新 更多