我正在开发一个应用程序来在不同的光照条件下提取 C# 中的文本。
我的问题是有时图像中有不同的亮度级别,如下所示:
所以我不能为整个图像使用预先计算的阈值,否则我会丢失一些字母。
我正在搜索可以将正确的阈值/二值化应用于图像的算法/片段/函数。
我在 AForge 中创建了这个BradleyLocalThresholding,它比其他非自适应方法更好,但它丢失了一些细节。(例如图像中的 G 变成 O )
任何人都可以向我建议更好的方法吗?
我正在开发一个应用程序来在不同的光照条件下提取 C# 中的文本。
我的问题是有时图像中有不同的亮度级别,如下所示:
所以我不能为整个图像使用预先计算的阈值,否则我会丢失一些字母。
我正在搜索可以将正确的阈值/二值化应用于图像的算法/片段/函数。
我在 AForge 中创建了这个BradleyLocalThresholding,它比其他非自适应方法更好,但它丢失了一些细节。(例如图像中的 G 变成 O )
任何人都可以向我建议更好的方法吗?
这非常困难,因为您的图像质量非常低,但您可以尝试迭代全局阈值方法,如下所示:
诀窍不是将其应用于整个图像,而是将图像分解为(例如)5x5 的块并将其单独应用于块,这将为您提供:
下面是 R 中的一个实现,我相信你可以重现
getT = 函数(y){ t = 平均值(y) mu1 = 平均值(y[y>=t]) mu2 = 平均值(y[y 1){ cmu1 = 平均值(y[y>=t]) cmu2 = mean(y[y 1 & cmu1 == mu1 & cmu2 == mu2){ 打印(粘贴('完成 t=',t)) 回报(t) 休息; }别的{ mu1 = cmu1 mu2 = cmu2 t = (mu1 + mu2)/2 打印(粘贴('新 t=',t)) } 我=我+1 } } r = seq(1, nrow(图像), by=5) c = seq(1, ncol(图像), by=5) r[长度(r)] = nrow(图像) c[长度(c)] = ncol(图像) y = 图像 for(i in 2:length(r) ){ for(j in 2:length(c) ){ 块 = 图像[r[i-1]:r[i], c[j-1]:c[j]] t = getT(块) y[r[i-1]:r[i], c[j-1]:c[j]] = (block>t)+0 } } 显示(y)
是的,使用 niblack(opencv 将它作为一个函数) - 基本上它使用局部平均值来构造一个变量阈值。它最适合 OCR。根据图像分辨率,您可能还希望在阈值处理之前将双三次上采样率提高 2 倍或 3 倍。
除了局部阈值之外的另一个选项是针对变化的照明进行调整。有一些方法试图校正照明并使其在整个图像中均匀。然后,您可以使用恒定阈值,或继续使用局部阈值,可能会取得更好的成功。如果图像与您显示的图像一样,那么您可以使用字母周围较亮的方块作为调整照明的关键。