图像中文本的局部阈值处理或二值化

时间:2013-04-30 20:35:07

标签: c# image-processing ocr image-recognition aforge

我正在开发一个应用程序来在不同光照条件下从C#中提取文本。

我的问题是有时图像中有不同的亮度级别,如下所示:

http://i.imgur.com/NJ2XTrn.png?1

所以我不能利用整个图像的预先计算的阈值,否则我会丢失一些字母。

我正在搜索算法/片段/功能,否则,可以对图像应用正确的阈值/二值化。

我在AForge中创建了这个BradleyLocalThresholding,比其他非自适应方法更好,但它丢失了一些细节。 (例如图像中的G变为O)

任何人都可以向我建议一个更好的方法吗?

3 个答案:

答案 0 :(得分:2)

是的,使用niblack(opencv将其作为函数) - 基本上它使用局部平均值来构造变量theshold。它最适合OCR。根据图像分辨率,您可能还希望在阈值处理之前以双倍上采样2倍或3倍。

答案 1 :(得分:2)

由于图像质量如此之低,因此非常困难,但您可以尝试迭代的全局阈值处理方法,如下所示:

  1. 随机选择初始估计阈值T(通常作为平均值)。
  2. 使用T对信号进行分段,这将产生两个组,G1由具有值< = T的所有点组成,并且G2由具有值> T的点组成。
  3. 计算G1和T点之间的平均距离,以及G2和T点。
  4. 计算新的阈值T =(M1 + M2)/ 2
  5. 重复步骤2到4,直到T的变化足够小。
  6. 诀窍不是将它应用于整个图像,而是将图像分解为(例如)5x5的块并将其单独应用于块,这将给你:

    enter image description here

    下面是R中的一个实现,我相信你可以重现

    getT = function(y){
      t = mean(y)
    
      mu1 = mean(y[y>=t])
      mu2 = mean(y[y 1){
          cmu1 = mean(y[y>=t])
          cmu2 = mean(y[y 1 & cmu1 == mu1 & cmu2 == mu2){
          print(paste('done t=', t))
          return(t)
          break;
        }else{
          mu1 = cmu1 
          mu2 = cmu2
          t = (mu1 + mu2)/2
          print(paste('new t=', t))
        }
        i = i+1
      }
    }
    
    
    r = seq(1, nrow(image), by=5)
    c = seq(1, ncol(image), by=5)
    r[length(r)] = nrow(image)
    c[length(c)] = ncol(image)
    y = image
    for(i in 2:length(r) ){
      for(j in 2:length(c) ){
        block = image[r[i-1]:r[i], c[j-1]:c[j]]
        t = getT(block)
        y[r[i-1]:r[i], c[j-1]:c[j]] = (block>t)+0
      }
    }
    
    display(y)
    

答案 2 :(得分:0)

除了局部阈值之外的另一个选择是调整变化的照明。有些方法试图校正照明并使其在整个图像中均匀。然后,您可以使用恒定阈值,或继续使用本地阈值,可能会获得更好的成功。如果图像与您显示的图像类似,那么您可以使用字母周围较亮的方块作为调整照明的关键。