我有一个表单(在右下角画了一行用于签名)被扫描为TIF格式(黑色/白色)。
有些填写表格的人可能会在表格上签名,而有些人则不会签名。那么,我怎么知道扫描图像上是否有签名呢?有任何算法建议,或任何现有的框架或库,可以实现这一点?
谢谢!
发布于 2015-11-23 17:16:02
这是我过去用来检查签名的代码。它假定图像的Bytes per pixel
为3。
MAX_BLACK_VALUE
数来自像素(255)的颜色的最大值乘以3(因为每个像素有一个字节3),然后减半。
代码的工作方式是总结签名图像中的像素数,如果它通过返回true的MinPixelCount
,即检测到签名。否则它会返回假的。
代码还使用Lockbits
(一种使图像处理速度更快的方法),如果java
有类似的方法,只需确保总是像在finally
语句中那样调用UnlockBits
。
private const int MAX_BLACK_VALUE = 382; // ((255 * 3) / 2) rounded down
private bool CheckForSignature(string SignatureFile, int MinPixelCount)
{
using (Bitmap bitmap = new Bitmap(SignatureFile))
{
int nBytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
try
{
byte[] baPixels = new byte[bitmapData.Stride * bitmap.Height];
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, baPixels, 0, baPixels.Length);
int nBlackPixels = 0;
for (int h = 0; h < bitmap.Height; h++)
{
int nCurrentLine = h * bitmapData.Stride;
for (int w = 0; w < (bitmap.Width * nBytesPerPixel); w += nBytesPerPixel)
{
int nBlue = baPixels[nCurrentLine + w];
int nGreen = baPixels[nCurrentLine + w + 1];
int nRed = baPixels[nCurrentLine + w + 2];
if (nBlue + nGreen + nRed <= MAX_BLACK_VALUE)
{
nBlackPixels++;
if (nBlackPixels >= MinPixelCount)
return true;
}
}
}
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
return false;
}
我意识到这是一个java
问题,但我只知道C#
,但你应该能够转换它。
发布于 2015-11-23 14:34:14
您可以对图像进行阈值化(将其转换为黑白),并总结出框内有多少黑色像素。您可以使用填充多少像素的百分比作为“在”签名字段中“绘制”的基本测试。这样做的缺点是,在定义阈值时,当阈值太高时,您可能会丢失更轻的签名,或者将空框错误地解释为填充(太低)。此外,所使用的钢笔的颜色将是一个需要考虑的因素。尽管如此,我们在这个应用程序中是幸运的,因为白纸黑字和笔迹之间的鲜明对比将对我们有利。
一种类似的方法可以使用互相关来计算空白签名框与应该已签名的签名框之间的差异,从而获得两者之间差异的值。很可能,与那些没有签名的框相比,被签名的框的错误要大得多。
您可能熟悉光学字符识别(optical字符识别),这是一种机器视觉方法,允许计算机对符号进行有意义的解释,尽管用人工书写很难做到这一点,因为它需要对系统进行“训练”,因为手写可能会有很大的变化。更糟糕的是,人们喜欢有自己的签名的风格闪光。但是,这种方法可能有些过分,因为您实际上不需要在软件中注册签名的每个字符。
您也可以使用形态(形状改变)技术,如扩张,侵蚀,或打开和关闭,试图夸大您的签名框中的区域的强度。我们不必担心数据形状的变形,因为我们只关心它们是否存在。然后,您可以使用blob计数来查看是否在边界内检测到足够的数据。
您应该尝试使用开放的图像处理工具包(如ImageJ )尝试使用不同的方法,该工具包预先打包了一些高级工具,您可以利用这些工具来确定哪种方法给您最好的指示。唯一的限制是你的创造力!
发布于 2015-11-23 14:28:57
我想看看OpenCV。
https://stackoverflow.com/questions/33873229
复制相似问题