如果有3个选项,使用c#或imagemagick,如何确定文档的背景颜色

我目前正在开发一个必须处理扫描表单的应用程序。 我的应用程序的任务之一是确定扫描哪种表单。 有3种可能的forms,具有独特的背景颜色,以识别每种forms。 可能的3种颜色是红色/粉红色,绿色和蓝色。 我遇到的问题是,我的尝试无法区分绿色和蓝色forms。 以下是绿色和蓝色示例文件的链接:

http://sofzh.miximages.com/c%23/Image0037.JPG

http://sofzh.miximages.com/c%23/Image0038.JPG

我正在使用C#.net Application和ImageMagick完成我需要执行的一些任务。

目前我正在获得扫描表格的颜色缩减直方图,并尝试确定表格中的颜色。 但我的应用程序无法区分绿色和蓝色。

任何建议或更聪明的方法都将很高兴。

谢谢,

埃里克

我觉得这很有趣,并且深入挖掘它。

获取位图的平均颜色的代码如何计算位图的平均rgb颜色值有一些问题,例如一些无效的强制转换和红/蓝通道交换。 这是一个固定版本:

private System.Drawing.Color CalculateAverageColor(Bitmap bm) { int width = bm.Width; int height = bm.Height; int red = 0; int green = 0; int blue = 0; int minDiversion = 15; // drop pixels that do not differ by at least minDiversion between color values (white, gray or black) int dropped = 0; // keep track of dropped pixels long[] totals = new long[] { 0, 0, 0 }; int bppModifier = bm.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb ? 3 : 4; // cutting corners, will fail on anything else but 32 and 24 bit images BitmapData srcData = bm.LockBits(new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, bm.PixelFormat); int stride = srcData.Stride; IntPtr Scan0 = srcData.Scan0; unsafe { byte* p = (byte*)(void*)Scan0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * stride) + x * bppModifier; red = p[idx + 2]; green = p[idx + 1]; blue = p[idx]; if (Math.Abs(red - green) > minDiversion || Math.Abs(red - blue) > minDiversion || Math.Abs(green - blue) > minDiversion) { totals[2] += red; totals[1] += green; totals[0] += blue; } else { dropped++; } } } } int count = width * height - dropped; int avgR = (int)(totals[2] / count); int avgG = (int)(totals[1] / count); int avgB = (int)(totals[0] / count); return System.Drawing.Color.FromArgb(avgR, avgG, avgB); } 

然而,在输入图像上运行此function时,两者都返回了一些难以区分的灰色,正如Will A在评论中已经预料到的那样,这就是为什么我从计算中删除了没有差异的任何颜色R,G和B之间至少15个

有趣的是,所谓的蓝色处方扫描平均G和B的值相等( R:214,G:237,B:237 )。 然而,绿色处方扫描导致G和B的值之间存在很大差异(18)( R:202,G:232,B:214 ),这可能是您应该研究的内容。 例如:

 if (color.G - color.B > 15) { form.Type = FormTypes.GreenForm } 

工作流程大纲:

  • 将图像转换为HSL / HSV颜色空间
  • 构建H通道的直方图
  • 直方图应在蓝色/绿色通道中显示清晰的峰值(至少为您的样品)

如果这不够独特,您可以通过某种方式对直方图投票进行加权以减少白色区域的影响(例如,在HSV颜色空间中,权重为S)。

我没有试过这个,但如何将图像大小调整为1×1像素(应该“平均”所有像素),然后检查该像素的色调,看它是否最接近红色,蓝色或绿色。

编辑

我没有安装ImageMagik,所以我用GetThumbnailImage攻击了它:

 private static bool ThumbnailCallback() { return false; } static void Main(string[] args) { var blueImage = Image.FromFile("blue.jpg").GetThumbnailImage(1, 1, new Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero); var blueBitmap = new Bitmap(blueImage); var blueHue = blueBitmap.GetPixel(0, 0).GetHue(); var greenImage = Image.FromFile("green.jpg").GetThumbnailImage(1, 1, new Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero); var greenBitmap = new Bitmap(greenImage); var greenHue = greenBitmap.GetPixel(0, 0).GetHue(); } 

使用你的图像我得到了blueHue值169.0909(真正的蓝色是180), greenHue等于140(纯绿色是120,青色是150)。

红色表格应该在0或360附近。

我知道你已经找到了答案 – 只是想我会给你另一种选择。

您是否可以从表单颜色中保存样本,然后扫描该表单时。 只是测试它,并区分任何样本这属于。