Ejemplo n.º 1
0
        public int getRegNumOfSheet(System.Drawing.Image image, XML.OMREnums.OMRSheet sheet, string OMRSheetFile, bool readInvalidRegNum) //parameters - panel1.BackgroundImage, OMREnums.OMRSheet.A550, "sheets.xml", false
        {
            Rectangle[] Blocks = new Rectangle[]                                                                                          //stores a set of four integers that represent the location & size of a rectangle
            {
                XML.OMRSheetReader.GetSheetPropertyLocation(OMRSheetFile, sheet, XML.OMREnums.OMRProperty.RegNumBlock),
            };

            List <Bitmap[]> bmps = new List <Bitmap[]>();   //list of bitmap objects, bitmap - pixel data for graphics image and its attributes

            bmps.Add(SliceOMarkBlock(image, Blocks[0], 3)); //image = panel1.BackgroundImage, location of reg no block, slices = 3 digits for reg no
            //fill the bitmap array with bitmap images of slice images of reg no block
            //SliceOMarkBlock method returns 3 sliced bitmap images of reg no block, those bitmap images are added to bmps list

            int regNum = 0, multiplier = 100;

            foreach (Bitmap[] blk in bmps)
            {
                foreach (Bitmap line in blk)//line = line containing numbers from 0 to 9
                {
                    try
                    {
                        int num = rateSlice(line, 10) - 1; //
                        if (num < 1 && !readInvalidRegNum)
                        {
                            throw new Exception("Invalid Reg. No.");
                        }
                        else
                        {
                            if (num < 0)
                            {
                                num = 0;
                            }
                            regNum     += num * multiplier;
                            multiplier /= 10;
                        }
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("Image is too noisy");
                    }
                }
            }


            return(regNum);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads all the selected options on paper in one call
        /// </summary>
        /// <param name="image">Exctracted Sheet.</param>
        /// <param name="sheet">Type of printed sheet</param>
        /// <param name="OMRSheetFile">XML sheet address</param>
        /// <returns></returns>
        public List <List <int> > getScoreOfSheet(System.Drawing.Image image, XML.OMREnums.OMRSheet sheet, string OMRSheetFile)
        {
            List <List <int> > scores = new List <List <int> >();

            //number of blocks depend upon type of sheet selected
            Rectangle[] Blocks = new Rectangle[
                XML.OMRSheetReader.GetSheetPropertyInt(OMRSheetFile, sheet, XML.OMREnums.OMRProperty.NumOfBlocks)
                                 ];
            // Read block location from XML file for selected sheet
            for (int i = 1; i <= Blocks.Length; i++)
            {
                Blocks[i - 1] = XML.OMRSheetReader.GetSheetPropertyLocation(OMRSheetFile, sheet, (XML.OMREnums.OMRProperty)i);
            }

            // slice the blocks into lines inside them and record as bitmap
            List <Bitmap[]> bmps = new List <Bitmap[]>();

            for (int i = 0; i < 4; i++)
            {
                bmps.Add(SliceOMarkBlock(image, Blocks[i], 10));
                scores.Add(new List <int>());
            }

            int bn = 0;

            // read selected option of sliced line
            foreach (Bitmap[] blk in bmps)
            {
                foreach (Bitmap line in blk)
                {
                    scores[bn].Add(rateSlice(line, 5));
                }
                bn++;
            }

            return(scores);
        }
Ejemplo n.º 3
0
        public int getRegNumOfSheet(System.Drawing.Image image, XML.OMREnums.OMRSheet sheet, string OMRSheetFile, bool readInvalidRegNum)
        {
            Rectangle[] Blocks = new Rectangle[]
            {
                XML.OMRSheetReader.GetSheetPropertyLocation(OMRSheetFile, sheet, XML.OMREnums.OMRProperty.RegNumBlock),
            };

            List <Bitmap[]> bmps = new List <Bitmap[]>();

            bmps.Add(SliceOMarkBlock(image, Blocks[0], 3));

            int regNum = 0, multiplier = 100;

            foreach (Bitmap[] blk in bmps)
            {
                foreach (Bitmap line in blk)
                {
                    int num = rateSlice(line, 10) - 1;
                    if (num < 1 && !readInvalidRegNum)
                    {
                        throw new Exception("Invalid Reg. No.");
                    }
                    else
                    {
                        if (num < 0)
                        {
                            num = 0;
                        }
                        regNum     += num * multiplier;
                        multiplier /= 10;
                    }
                }
            }

            return(regNum);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Detects, wrapps and crops out OMR sheet from flattened camera/scanner image.
        /// Flattened image is got by using method,  private Bitmap flatten(Bitmap bmp, int fillint, int contint);
        /// </summary>
        /// <param name="bitmap">Bitmap image to process</param>
        /// <param name="basicImage">Backup image in case extraction fails</param>
        /// <param name="minBlobWidHei">Pre-configured variable, to be queried from XML reader</param>
        /// <param name="fillint">Pre-configured int, to be queried from XML reader</param>
        /// <param name="contint">Pre-configured int, to be queried from XML reader</param>
        /// <param name="OMRSheets">Sheets XML File Address</param>
        /// <param name="tb">Textbox to give in'process details on</param>
        /// <param name="panel1">Panel to draw in-process changes on.</param>
        /// <param name="giveFB">True when In- Process Feedback is required.</param>
        /// <param name="sheet">Type of sheet from OMREnums</param>
        /// <returns>Cropped OMR sheet (if detected) from camera/scanner image.</returns>
        private Bitmap ExtractPaperFromFlattened(Bitmap bitmap, Bitmap basicImage, int minBlobWidHei, int fillint, int contint, string OMRSheets, ref TextBox tb, ref Panel panel1, bool giveFB, XML.OMREnums.OMRSheet sheet)
        {
            // lock image, Bitmap itself takes much time to be processed
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight   = minBlobWidHei; // both these variables have to be given when calling the
            blobCounter.MinWidth    = minBlobWidHei; // method, the can also be queried from the XML reader using OMREnums

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            Graphics g         = Graphics.FromImage(bitmap);
            Pen      yellowPen = new Pen(Color.Yellow, 2); // create pen in case image extraction failes and we need to preview the

            //blobs that were detected

            Rectangle[] rects  = blobCounter.GetObjectsRectangles();
            Blob[]      blobs2 = blobCounter.GetObjects(bitmap, false);

            //Detection of paper lies within the presence of crossmark printed on the corneres of printed sheet.
            // First, detect left edge.
            System.Drawing.Image compImg = System.Drawing.Image.FromFile("lc.jpg");
            // lc.jpg = Mirrored image sample as located on the corner of printed sheet
            UnmanagedImage compUMImg = UnmanagedImage.FromManagedImage((Bitmap)compImg);
            // this helps filtering out much smaller and much larger blobs depending upon the size of image.
            // can be queried from XML Reader
            double minbr = XML.OMRSheetReader.getProcessVariableD(OMRSheets, sheet, XML.OMREnums.OMRImageProcessVariables.MinBlobRatio);
            double maxbr = XML.OMRSheetReader.getProcessVariableD(OMRSheets, sheet, XML.OMREnums.OMRImageProcessVariables.MaxBlobRatio);

            List <IntPoint> quad = new List <IntPoint>(); // Store sheet corner locations (if anyone is detected )

            if (giveFB)
            {
                showTimeStamp("Left edge detection started.", ref tb);
            }
            try
            {
                foreach (Blob blob in blobs2)
                {
                    if (
                        ((double)blob.Area) / ((double)bitmap.Width * bitmap.Height) > minbr &&
                        ((double)blob.Area) / ((double)bitmap.Width * bitmap.Height) < maxbr &&
                        blob.Rectangle.X < (bitmap.Width) / 4)     // filters oout very small or very larg blobs
                    {
                        if ((double)blob.Rectangle.Width / blob.Rectangle.Height < 1.4 &&
                            (double)blob.Rectangle.Width / blob.Rectangle.Height > .6) // filters out blobs having insanely wrong aspect ratio
                        {
                            compUMImg = UnmanagedImage.FromManagedImage(ImageUtilities.ResizeImage(compImg, blob.Rectangle.Width, blob.Rectangle.Height));
                            if (isSame(blob.Image, compUMImg))
                            {
                                g.DrawRectangle(yellowPen, blob.Rectangle);
                                quad.Add(new IntPoint((int)blob.CenterOfGravity.X, (int)blob.CenterOfGravity.Y));
                            }
                        }
                    }
                }
            }
            catch (ArgumentException) { MessageBox.Show("No Blobs"); }
            if (giveFB)
            {
                showTimeStamp("Left edge detection finished.", ref tb);
            }
            try
            { // Sort out the list in right sequence, UpperLeft,LowerLeft,LowerRight,upperRight
                if (quad[0].Y > quad[1].Y)
                {
                    IntPoint tp = quad[0];
                    quad[0] = quad[1];
                    quad[1] = tp;
                }
            }
            catch
            {
            }
            compImg   = System.Drawing.Image.FromFile("rc.jpg");
            compUMImg = UnmanagedImage.FromManagedImage((Bitmap)compImg);
            if (giveFB)
            {
                showTimeStamp("Right edge detection started.", ref tb);         // jusst like left edge detection
            }
            try
            {
                foreach (Blob blob in blobs2)
                {
                    if (
                        ((double)blob.Area) / ((double)bitmap.Width * bitmap.Height) > minbr &&
                        ((double)blob.Area) / ((double)bitmap.Width * bitmap.Height) < maxbr &&
                        blob.Rectangle.X > (bitmap.Width * 3) / 4)
                    {
                        if ((double)blob.Rectangle.Width / blob.Rectangle.Height < 1.4 &&
                            (double)blob.Rectangle.Width / blob.Rectangle.Height > .6)
                        {
                            compUMImg = UnmanagedImage.FromManagedImage(ImageUtilities.ResizeImage(compImg, blob.Rectangle.Width, blob.Rectangle.Height));
                            if (isSame(blob.Image, compUMImg))
                            {
                                g.DrawRectangle(yellowPen, blob.Rectangle);
                                quad.Add(new IntPoint((int)blob.CenterOfGravity.X, (int)blob.CenterOfGravity.Y));
                            }
                        }
                    }
                }
            }
            catch (ArgumentException) { MessageBox.Show("No Blobs"); }
            if (giveFB)
            {
                showTimeStamp("Right edge detection finished.", ref tb);
            }
            try
            {
                if (quad[2].Y < quad[3].Y)
                {
                    IntPoint tp = quad[2];
                    quad[2] = quad[3];
                    quad[3] = tp;
                }
            }
            catch
            {
            }

            yellowPen.Dispose();
            g.Dispose();
            //Again, filter out if wrong blobs pretended to our blobs.
            if (quad.Count == 4)
            {
                if (((double)quad[1].Y - (double)quad[0].Y) / ((double)quad[2].Y - (double)quad[3].Y) < .75 ||
                    ((double)quad[1].Y - (double)quad[0].Y) / ((double)quad[2].Y - (double)quad[3].Y) > 1.25)
                {
                    quad.Clear(); // clear if, both edges have insanely wrong lengths
                }
                else if (quad[0].X > bitmap.Width / 2 || quad[1].X > bitmap.Width / 2 || quad[2].X < bitmap.Width / 2 || quad[3].X < bitmap.Width / 2)
                {
                    quad.Clear(); // clear if, sides appear to be "wrong sided"
                }
            }
            if (quad.Count != 4)   // sheet not detected, reccurrsive call.
            {
                if (contint <= 60) //try altering the contrast correction on both sides of numberline
                {
                    if (contint >= 0)
                    {
                        contint += 5;
                        contint *= -1;
                        return(ExtractOMRSheet(basicImage, fillint, contint, OMRSheets, ref panel1, ref tb, giveFB, sheet));
                    }
                    else
                    {
                        contint *= -1;
                        contint += 10;
                        return(ExtractOMRSheet(basicImage, fillint, contint, OMRSheets, ref panel1, ref tb, giveFB, sheet));
                    }
                }
                else // contrast correction yeilded no result
                {
                    MessageBox.Show("Extraction Failed.");
                    return(basicImage);
                }
            }
            else // sheet found
            {
                IntPoint tp2 = quad[3];
                quad[3] = quad[1];
                quad[1] = tp2;
                //sort the edges for wrap operation
                QuadrilateralTransformation wrap = new QuadrilateralTransformation(quad);
                wrap.UseInterpolation = false; //perspective wrap only, no binary.
                Rectangle sr = XML.OMRSheetReader.GetSheetPropertyLocation(OMRSheets, sheet, XML.OMREnums.OMRProperty.SheetSize);
                wrap.AutomaticSizeCalculaton = false;
                wrap.NewWidth  = sr.Width;
                wrap.NewHeight = sr.Height;
                wrap.Apply(basicImage).Save("LastImg.jpg", ImageFormat.Jpeg); // creat file backup for future use.
                return(wrap.Apply(basicImage));                               // wrap
            }
        }
Ejemplo n.º 5
0
 private Bitmap ExtractOMRSheet(Bitmap basicImage, int fillint, int contint, string OMRSpecsSheetAddress, ref Panel panel1, ref TextBox textBox1, bool giveFB, XML.OMREnums.OMRSheet sheet)
 {
     ts = new TimeSpan(DateTime.Now.Ticks);
     System.Drawing.Image flattened = (System.Drawing.Image)flatten(basicImage, fillint, contint);
     if (giveFB)
     {
         showTimeStamp("Flatting Started", ref textBox1);
         panel1.BackgroundImage = flattened;
         showTimeStamp("Flattened", ref textBox1);
         panel1.Invalidate();
         Application.DoEvents();
         showTimeStamp("OMR Extraction Started", ref textBox1);
     }
     return(ExtractPaperFromFlattened(new Bitmap(flattened), basicImage, 3, fillint, contint, OMRSpecsSheetAddress, ref textBox1, ref panel1, giveFB, sheet));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Extracts image and gives "In-Process" feebback on referenced panel and text box
        /// </summary>
        /// <param name="SmallCameraImage">any small image, as smaller as 3MP is recomended and enough clear. Bigger images take alot of time to be processed</param>
        /// <param name="OMRSpecsSheetAddress">XML sheet specification file</param>
        /// <param name="panel1"></param>
        /// <param name="textBox1"></param>
        /// <returns></returns>

        public Bitmap ExtractOMRSheet(Bitmap SmallCameraImage, string OMRSpecsSheetAddress, ref Panel panel1, ref TextBox textBox1, XML.OMREnums.OMRSheet sheet)
        {
            return(ExtractOMRSheet(SmallCameraImage, 0, 0, OMRSpecsSheetAddress, ref panel1, ref textBox1, true, sheet));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Extracts Images from smallSize CameraImage, No feed Back given during process
        /// </summary>
        /// <param name="SmallCameraImage"></param>
        /// <param name="OMRSpecsSheetAddress"></param>
        /// <returns>Formated, Right sized OMR Sheet</returns>
        public Bitmap ExtractOMRSheet(Bitmap SmallCameraImage, string OMRSpecsSheetAddress, XML.OMREnums.OMRSheet sheet)
        {
            Panel   p = new Panel();
            TextBox t = new TextBox();

            t.Text = "";
            return(ExtractOMRSheet(SmallCameraImage, 0, 0, OMRSpecsSheetAddress, ref p, ref t, false, sheet));
        }