OCR 的二进制矩阵居中

Centering of binary matrix for OCR

我正在将图像中的字符读入 20x20 的块中以执行光学字符识别 (OCR),并且想知道如何实现使二进制数据矩阵居中的最佳方法。

例如,字符 h 可能会转换为以下 一维 数组(为清楚起见添加了空格和换行符):

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

据我所知,有两种选择:

  1. 质心

    var mass = 0,
        sum = {
          x: 0,
          y: 0
        };
    
    for(y = 0; y < size; y++) {
      for(x = 0; x < size; x++) {
        if(chunk[size * y + x]) {
          sum.x += x;
          sum.y += y;
          mass++;
        }
      }
    }
    
    // diff center of mass and center of matrix
    var diff = {
      x: Math.round((size / 2) - (sum.x / mass)),
      y: Math.round((size / 2) - (sum.y / mass))
    };
    
    // move 1's accordingly
    

    问题是如果这种类型的居中导致任何 1 被放置在块之外并因此破坏数据,该如何处理?

  2. 边界框

    计算min(x, y)max(x, y)的中心以及与矩阵中心的差值。

如果输入字符在两个维度上随机(轻微)扭曲,其中哪一个会产生最佳(最一致)的结果?

生成的块用于训练多层感知器 (MLP) 神经网络(如果有帮助的话)。

最终使用边界框方法:

var min = {
  x: size,
  y: size
};
var max = {
  x: 0,
  y: 0
};

for(y = 0; y < size; y++) {
  for(x = 0; x < size; x++) {
    if(chunk[size * y + x]) {
      if(min.x > x)
        min.x = x;

      if(min.y > y)
        min.y = y;

      if(max.x < x)
        max.x = x;

      if(max.y < y)
        max.y = y;
    }
  }
}

var diff = {
  x: Math.floor((size / 2) - (min.x + (max.x - min.x) / 2)),
  y: Math.floor((size / 2) - (min.y + (max.y - min.y) / 2))
};

// move 1's accordingly