【问题标题】:Matlab: Differentiate between p and dMatlab:区分p和d
【发布时间】:2017-12-02 12:50:36
【问题描述】:

我正在尝试编写一个脚本来自动评估测试(D2 集中耐力测试) 此处显示示例图像:

目标是将所有 d 与 to 划线:因此,您必须在字母下方划线 2 划线、上方划线 2 划线、下方划线 1 划线和上方划线 1 划线。

所以我的主要问题是:如何自动区分打印的字母是 d 还是 p? 是否有一个指标可以应用于所有字母,以区分这两个字母?我尝试了熵,但使用该指标无法辨别差异。

我已经尝试过 OCR,但奇怪的是,ocr 不会为我输入的字母返回任何结果。而且我认为 ocr 可能没有必要——我只是想区分 p 和 d——也许是 ocr这有点矫枉过正?这就是为什么我认为一个简单的指标就足够了..

感谢您的帮助!!

【问题讨论】:

  • 是的——我试过了,但奇怪的是,ocr 不会为我输入的字母返回任何结果。而且我认为 ocr 可能没有必要——我只是想区分 p和 d's - 也许一个 ocr 有点矫枉过正?这就是为什么我认为一个简单的指标就足够了..

标签: image matlab image-processing text


【解决方案1】:

通过选择一个能够最小化 Wasserstein(地球移动器)距离的质心,我能够获得相当不错的性能。我下载了一些 9 和 6 的手写数字 here 来测试这一点,并且能够在不费力气的情况下获得大约 98-99% 的分类准确度。我选择了 9 和 6,因为它们的旋转对称性类似于您问题中的 p 和 d。

我总共有 1000 张 6 的图像和 1000 张 9 的图像,每个 28 x 28 像素。像素强度不是二进制的,但二进制像素的性能仍然很好。

通过在图像上使用 Wasserstein 距离,您可以将观察到的像素位置视为像素网格上随机分布的实现。也就是说,对于数字 6 和 9,存在一个关于像素最终位置的分布。然后,对于每个单独的图像,获得的值可以看作是从这个分布中观察到的经验样本。这将问题从被视为“每个图像都是一个数据点”变成了更像是“每个观察到的像素都是一个数据点”。 Wasserstein 距离是关于概率度量的度量,因此以这种方式构图图像可以让您使用并非立即明显适用的距离度量。

Wasserstein 距离然后计算“需要移动多少质量”才能将一种分布转变为另一种分布。这对于非原子分布来说很复杂,但是对于原子分布来说,这变成了求解线性程序,并且很多人已经开发了各种软件来做到这一点。在 Matlab 中很好的 Wasserstein 距离实现可以在 here 找到。

这个函数接受 5 个参数并给出两个值:

[x, fval] = emd(F1, F2, W1, W2, Func)

对于我们的目的,F1 和 F2 是图像(稍后会详细介绍),W1 和 W2 是原子的权重。因为我们将图像视为未加权的经验分布,我们可以将 W1 和 W2 指定为均匀加权。 Func 是上一个链接中提供的函数。重要的输出是实值 fval 结果,它给出了将 F1 中的质量移动到 F2 的成本。这是我们的“距离”,也是我们想要在分类中最小化的东西。

假设您有一些预先分类的图像,通过对已知的 6 和 9 求平均来得出分布的“质心”。将这些质心定义为:

% Have "canonical example" from known images
6_centroid = mean(known_sixes,3);
9_centroid = mean(known_nines,3);
% Construct storage vectors for classifications
6_classify = zeros(1,num_testing);
9_classify = zeros(1,num_testing);
% Classify each image according to which centroid is closest in Wasserstein distance:
for j = 1:num_testing
% Compute the distance between each of the testing images for nines versus the centroid for 6's
       [flow6,cost_of_flow6]=emd(test_9(:,:,j),6_centroid,(1/28)*ones(1,28),(1/28)*ones(1,28),@gdf); 
    % Compute the distance between each of the testing images for nines versus the centroid for 9's
       [flow9,cost_of_flow9]=emd(test_9(:,:,j),9_centroid,(1/28)*ones(1,28),(1/28)*ones(1,28),@gdf); 
       % Classify based on minimizing Wasserstein Distance
       if cost_of_flow6<=cost_of_flow9
           nine_classify(j) = 6;
       else
           nine_classify(j) = 9;
       end
    % Compute the distance between each of the testing images for sixes versus the centroid for 6's
       [flow6,cost_of_flow6]=emd(test_6(:,:,j),6_centroid,(1/28)*ones(1,28),(1/28)*ones(1,28),@gdf); 
    % Compute the distance between each of the testing images for sixes versus the centroid for 9's
       [flow9,cost_of_flow9]=emd(test_6(:,:,j),9_centroid,(1/28)*ones(1,28),(1/28)*ones(1,28),@gdf); 
       % Classify based on minimizing Wasserstein Distance
       if cost_of_flow6<=cost_of_flow9
           six_classify(j) = 6;
       else
           six_classify(j) = 9;
       end
end

重要提示 这里要注意的一件重要的事情,它会极大地影响性能,那就是您如何指定行和列。 emd 函数不一定将图像视为二维空间中像素上的分布,而是将图像视为行或列上的分布,具体取决于图像的方向。例如,如果您将图像的行视为样本,那么对于 6 和 9(可能还有 p 和 d),分布不会在推土机距离上分离得那么好,因为 9 和 6 都集中了它们的大部分质量朝向水平轴的中心。

但是,如果您将列视为样本,您会发现 9 的分布严重偏向顶部,而 6 则偏向底部。此外,由于数字高于宽度,因此必须发生额外的质量移动,因为“物质”必须移动更远的距离。这使得选择列作为样本可以提供更好的性能(98% 对 73% 的准确度)。 p 和 d 也可能是这样。

【讨论】:

  • 您好,非常感谢您的帮助!!我真的没想到在一篇文章中会有这么多的投入。我使用 6's 和 9's - 数据库重新实现了您的方法。但我不确定如何实施您的最后评论。如何更改指定行和列的方式?我确实理解您的观点,但我不确定如何将其转换为代码..
  • 只要确保图像是垂直输入的(不要转置)。
  • 哇——现在我的准确率也达到了 95%/98%。我将为 d 和 p 生成一个测试集并用它们进行测试。我会让你知道它是如何工作的!
  • 与使用 NN 之类的方法相比,您肯定可以获得更好的分类准确度,但如果您想要一种使用距离度量的方法,我认为 EMD 非常好。
猜你喜欢
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多