Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
466 views
in Technique[技术] by (71.8m points)

image - How to determine the background color of document when there are 3 options, using c# or imagemagick

i am currently developing an application that has to process scanned forms. One of the tasks of my application is to determine which kind of form is scanned. There are 3 possible types of forms with a unique background color to identify each kind. The 3 colors that are possible are red/pink, green and blue. The problem i am having is, that my attempts fail to distinguish between the green and blue forms. Here are links to the green and blue sample files:

http://dl.dropbox.com/u/686228/Image0037.JPG

http://dl.dropbox.com/u/686228/Image0038.JPG

I am using C# .net Application and ImageMagick for some tasks i need to perform.

Currently i am getting color reduced histogram of my scanned form and try to determine which colors are in the form. But my app can't rely distinguish the green and blue ones.

Any advise or maybe a smarter approach would be gladly appreciated.

Thanks,

Erik

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I found this rather interesting and dug into it a little deeper.

The code to get the average color of a bitmap found at How to calculate the average rgb color values of a bitmap had problems like some invalid casts and red/blue channels swapped. Here is a fixed version:

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);
}

Running this function on your input images, however, returned some indistinguishable grayish color for both of them, as already anticipated by Will A in the comments, which is why i'm dropping any colors from the calculation that do not have a difference of at least 15 between R, G and B.

The interesting thing is that the supposedly blue prescription scan averages equal values for G and B (R: 214, G: 237, B: 237). However the green prescription scan resulted in a big difference (18) between the values for G and B (R: 202, G: 232, B: 214) so that might be what you should be looking into. Ex:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...