AForge.NET

  :: AForge.NET Framework :: Articles :: Forums ::

Problem on glyphSize

Forum to discuss Glyph Recognition And Tracking Framework project, its features, applications, etc.

Problem on glyphSize

Postby puria » Wed Jul 13, 2011 3:27 pm

I change glyphSize to glyphSizewidth and glyphSizeheight in SquareBinaryGlyphRecognizer.cs and in recognizer

Code: Select all
  QuadrilateralTransformation quadrilateralTransformation = new QuadrilateralTransformation(corners, blob.Rectangle.Width * 5, blob.Rectangle.Height * 5);

                    Bitmap transformed = quadrilateralTransformation.Apply(grayImage);


                    OtsuThreshold otsuThresholdFilter = new OtsuThreshold();
                    Bitmap transformedOtsu = otsuThresholdFilter.Apply(transformed);
                    double blobwidth = blob.Rectangle.Width;
                    double blobheight = blob.Rectangle.Height;
                    int glyphSizewidth = System.Convert.ToInt16(Math.Floor(blobwidth / 10));
                    int glyphSizeheight = System.Convert.ToInt16(Math.Floor(blobheight / 10));

                    SquareBinaryGlyphRecognizer gr = new SquareBinaryGlyphRecognizer(glyphSizewidth, glyphSizeheight);

                    bool[,] glyphValues = gr.Recognize(transformedOtsu,   new Rectangle(0, 0, blob.Rectangle.Width * 5, blob.Rectangle.Height * 5));


                    StringBuilder sb = new StringBuilder("");


                        for (int i = 0; i < glyphSizewidth; i++)
                        {
                            for (int j = 0; j < glyphSizeheight; j++)
                            {
                                sb.Append((glyphValues[i, j]) ? "1" : "0");

                            }
                            textBox1.Text = sb.ToString() ;
                        }
                    }
                    pictureBox3.Image = transformedOtsu;
                    counter++;

I have no problem with object that have equal width and height and it work correctly ,but when object have different width and height , glyphValues show wrong result ,also a compiler error occurred while height is bigger than width.
whats problem on SquareBinaryGlyphRecognizer that can't recognize object with different width and height?
Please help me out.
Attachments
Untitled.jpg
it show 100110011011 or
100
110
011
011
Untitled.jpg (11.38 KiB) Viewed 5389 times
puria
 
Posts: 7
Joined: Thu Feb 24, 2011 8:36 am

Re: Problem on glyphSize

Postby andrew.kirillov » Wed Jul 13, 2011 4:06 pm

puria wrote:whats problem on SquareBinaryGlyphRecognizer that can't recognize object with different width and height?

No problems as long as you've implemented it correctly. If it does not work, than most probably you did something wrong in SquareBinaryGlyphRecognizer.

In general square glyphs are preferred. Because if you have 5x5 glyph rotated by 90 degrees, than it is still 5x5 glyph. But if you deal with glyphs of 4x3 size, for example, then after rotating it may become 3x4. Since you don't know for sure which is the first corner of the glyph found by quadrilateral finder, you may provide either 4x3 or 3x4 glyph image to an image processing routine which expects 4x3. Anyway, it is not an issue to update SquareBinaryGlyphRecognizer to process none square glyphs. But you may get problems, when you start using such version in something like glyph recognition in video feeds - it will become your responsibility to detect direction of glyph image and correct it.
With best regards,
Andrew


Interested in supporting AForge.NET Framework?
User avatar
andrew.kirillov
Site Admin, AForge.NET Developer
 
Posts: 3243
Joined: Fri Jan 23, 2009 9:12 am
Location: UK

Re: Problem on glyphSize

Postby puria » Fri Sep 30, 2011 4:54 pm

No problems as long as you've implemented it correctly. If it does not work, than most probably you did something wrong in SquareBinaryGlyphRecognizer.

please see the following code , maybe i'm done something wrong in SquareBinaryGlyphRecognizer:
Code: Select all
    class SquareBinaryGlyphRecognizer
    {

        private int glyphSizewidth, glyphSizeheight;




        public SquareBinaryGlyphRecognizer(int glyphSizewidth, int glyphSizeheight)
        {
            this.glyphSizewidth = glyphSizewidth;
            this.glyphSizeheight = glyphSizeheight;
        }

       
        public byte[,] Recognize(Bitmap image, Rectangle rect, out   float confidence)
        {
            BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
                ImageLockMode.ReadWrite, image.PixelFormat);

            try
            {
                return Recognize(new UnmanagedImage(data), rect, out  confidence);
            }
            finally
            {
                image.UnlockBits(data);
            }
        }

   
        public byte[,] Recognize(UnmanagedImage image, Rectangle rect, out float confidence)
        {
            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new UnsupportedImageFormatException("Pixel format of the specified image is not supported.");
            }

            int glyphStartX = rect.Left;
            int glyphStartY = rect.Top;

            int glyphWidth = rect.Width;
            int glyphHeight = rect.Height;

            // glyph's cell size
            int cellWidth = glyphWidth / glyphSizewidth;
            int cellHeight = glyphHeight / glyphSizeheight;

            // allow some gap for each cell, which is not scanned
            int cellOffsetX = (int)(cellWidth * 0.1);
            int cellOffsetY = (int)(cellHeight * 0.1);

            // cell's scan size
            int cellScanX = (int)(cellWidth * 0.8);
            int cellScanY = (int)(cellHeight * 0.8);
            int cellScanArea = cellScanX * cellScanY;

            int[,] cellIntensity = new int[glyphSizewidth, glyphSizeheight];
            unsafe
            {
                int stride = image.Stride;

                byte* srcBase = (byte*)image.ImageData.ToPointer() +
                    (glyphStartY + cellOffsetY) * stride + glyphStartX + cellOffsetX;
                byte* srcLine;
                byte* src;

                // for all glyph's rows
                for (int gi = 0; gi < glyphSizewidth; gi++)
                {
                    srcLine = srcBase + cellHeight * gi * stride;

                    // for all lines in the row
                    for (int y = 0; y < cellScanY; y++)
                    {

                        // for all glyph columns
                        for (int gj = 0; gj < glyphSizeheight; gj++)
                        {
                            src = srcLine + cellWidth * gj;

                            // for all pixels in the column
                            for (int x = 0; x < cellScanX; x++, src++)
                            {
                                cellIntensity[gi, gj] += *src;
                            }
                        }

                        srcLine += stride;
                    }
                }
            }

            // calculate value of each glyph's cell and set confidence to minim value
            byte[,] glyphValues = new byte[glyphSizewidth, glyphSizeheight];
            confidence = 1f;

            for (int gi = 0; gi < glyphSizewidth; gi++)
            {
                for (int gj = 0; gj < glyphSizeheight; gj++)
                {
                    float fullness = (float)(cellIntensity[gi, gj] / 255) / cellScanArea;
                    float conf = (float)System.Math.Abs(fullness - 0.5) + 0.5f;

                    glyphValues[gi, gj] = (byte)((fullness > 0.5f) ? 1 : 0);

                    if (conf < confidence)
                        confidence = conf;
                }
            }

            // (for debugging) draw lines showing cells' gaps and scan area
            for (int gi = 0; gi < glyphSizewidth; gi++)
            {
                Drawing.Line(image,
                    new IntPoint(glyphStartX, glyphStartY + cellHeight * gi),
                    new IntPoint(glyphStartX + glyphWidth, glyphStartY + cellHeight * gi),
                    Color.FromArgb(128, 128, 128));

                Drawing.Line(image,
                    new IntPoint(glyphStartX, glyphStartY + cellHeight * gi + cellOffsetY),
                    new IntPoint(glyphStartX + glyphWidth, glyphStartY + cellHeight * gi + cellOffsetY),
                    Color.FromArgb(192, 192, 192));

                Drawing.Line(image,
                    new IntPoint(glyphStartX, glyphStartY + cellHeight * gi + cellOffsetY + cellScanY),
                    new IntPoint(glyphStartX + glyphWidth, glyphStartY + cellHeight * gi + cellOffsetY + cellScanY),
                    Color.FromArgb(192, 192, 192));

            }

            for (int gj = 0; gj < glyphSizeheight; gj++)
            {
                Drawing.Line(image,
                    new IntPoint(glyphStartX + cellWidth * gj, glyphStartY),
                    new IntPoint(glyphStartX + cellWidth * gj, glyphStartY + glyphHeight),
                    Color.FromArgb(128, 128, 128));

                Drawing.Line(image,
                    new IntPoint(glyphStartX + cellWidth * gj + cellOffsetX, glyphStartY),
                    new IntPoint(glyphStartX + cellWidth * gj + cellOffsetX, glyphStartY + glyphHeight),
                    Color.FromArgb(192, 192, 192));

                Drawing.Line(image,
                    new IntPoint(glyphStartX + cellWidth * gj + cellOffsetX + cellScanX, glyphStartY),
                    new IntPoint(glyphStartX + cellWidth * gj + cellOffsetX + cellScanX, glyphStartY + glyphHeight),
                    Color.FromArgb(192, 192, 192));
            }

            return glyphValues;

        }

    }

i'm also changed some stuff in main code so there isn't any rotation:
Code: Select all
           foreach (Blob blob in bloblist )
            {
                int glyphSizew = 20;
                int glyphSizeh = 15;
                   Crop cropfilter = new Crop(new Rectangle(blob.Rectangle.X,Convert.ToInt16(blob.Rectangle.Y -1.1)
                        , Convert.ToInt16(blob.Rectangle.Width * 1.1),blob.Rectangle.Height * 2));

                Bitmap bitmap1 = cropfilter.Apply(bitmap);

                ResizeBicubic rbfilter = new ResizeBicubic(bitmap1.Width * 5, bitmap1.Height * 5);
                Bitmap bb = rbfilter.Apply(bitmap1);
                OtsuThreshold filter = new OtsuThreshold ();
                Bitmap bbb = filter.Apply(bb);

                SquareBinaryGlyphRecognizer sq = new SquareBinaryGlyphRecognizer(glyphSizew, glyphSizeh);
                byte[,] glyphValues = sq.Recognize(bbb, new Rectangle(0, 0, bitmap1.Width * 5, bitmap1.Height * 5), out confidence);

                StringBuilder sb = new StringBuilder("");

                for (int i = 0; i < glyphSizew; i++)
                {
                    for (int j = 0; j < glyphSizeh; j++)
                    {
                        sb.Append(Convert.ToBoolean(glyphValues[i, j]) ? "1" : "0");
                        sb.Append(" ");
                    }

                    sb.AppendLine("\n");

                }
                sb.AppendLine("\n");
               
                textBox1.AppendText(sb.ToString());

ResizeBicubic.jpg
ResizeBicubic.jpg (5.11 KiB) Viewed 5187 times


1.jpg
if glyphSizew = 20
glyphSizeh = 15
result is:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1
0 0 0 0 0 0 1 1 0 0 0 0 1 1 1
0 0 0 0 0 0 0 1 0 0 0 0 1 1 1
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1.jpg (28.93 KiB) Viewed 5187 times

and it work correctly if have equal glyphSize:
2.jpg
if glyphSizew = 20
glyphSizeh = 20
result is:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2.jpg (35.23 KiB) Viewed 5187 times


could anyone help me?
puria
 
Posts: 7
Joined: Thu Feb 24, 2011 8:36 am




Return to GRATF

cron