Create OMR template from image using Aspose.OMR for .NET

How to generate OMR template (.omr) from existing image, instead of creating from text file ?

When I am processing image, i found following issue, please help. I also attached existing image that I need to convert it into .omr template, so that bubblesheet answer can be recognize and get extratcted data in csv.

bubblesheetImage.JPG (92.4 KB)

Error when converting exiting image into .omr template file.

Request processing caused an exception. Try to change the input, check files uploaded, contact support. Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed) nPPolygons > 0 in function 'filterN Error reference ID 7010d9f8-fb6c-4984-b0c9-d6359bb253df

Please help.

@bvaidya

Thanks for contacting support.

Currently Aspose.OMR for .NET supports OMR operation using prepared templates. A feature request to create template from image has been logged as OMR-417 in our issue tracking system. We will further investigate feasibility of this feature and let you know as soon as feature is available. Please spare us little time.

We are sorry for the inconvenience.

@asad.ali
Thanks for your prompt reply.

I was trying to generate template as per my need, but using prepared template, I am not able to generate template(.omr). I am evaluating your aspose OMR product and willing to purchase if you can generate exact same template from your end. I have attached here. AnswerSheet Template.jpg (88.9 KB)

Also my credit limit for free trial reached to 51, can you please increase so that I also try to generate template as per my need.

@bvaidya

Thanks for writing back.

As shared earlier, Aspose.OMR for .NET does not support template generation at the moment and a feature request has already been logged into our issue tracking system for the sake of implementation. We will surely let you know as soon as we have some definite updates regarding feature availability.

You may please post your above request in Aspose.Purchase forum where you will definitely be assisted accordingly.

@asad.ali

Error occurred

Request processing caused an exception. Try to change the input, check files uploaded, contact support. Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed) nPPolygons > 0 in function 'filterN Error reference ID 79c27076-ceae-485d-abec-5a2110f7c549

OK


Error occurred

Request processing caused an exception. Try to change the input, check files uploaded, contact support. Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed) nPPolygons > 0 in function 'filterN Error reference ID 79c27076-ceae-485d-abec-5a2110f7c549

OK


Error occurred

Request processing caused an exception. Try to change the input, check files uploaded, contact support. Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed) nPPolygons > 0 in function 'filterN Error reference ID 0c083f42-bb4e-48c7-8bd2-05d62da7253a

OK


Error occurred

Request processing caused an exception. Try to change the input, check files uploaded, contact support. Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed) nPPolygons > 0 in function 'filterN Error reference ID 16c8f2dd-b1e4-44f5-a56a-e3308081eca8

OK
Can’t filter nested polygons: subdiv failure 2. Reason: OpenCV(4.0.1) /home/maxx/git/OMR.Kernel/Dependencies/opencv-4.0.1/modules/imgproc/src/geometry.cpp:623: error: (-215:Assertion failed
image.png (105.4 KB)

@bvaidya

Would you please share some more details like what code snippet you are using so that we can test the scenario in our environment and address it accordingly.

@asad.ali,

We have use following code snippet to process omr sheet.

namespace Aspose.OMR.ConsoleDemo
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.OleDb;
    using System.IO;
    using System.Linq;
    using Api;
    using Model;

    public class Program
    {
        // Test data should be located under "TestData" folder in solution directory
        private static readonly string TestDataFolderName = @"TestData";

        /// <summary>
        /// Template for testing
        /// </summary>
//        private static readonly string TemplateName = @"Sheet.omr";
        private static readonly string TemplateName = @"TestTemplate2.omr";


        /// <summary>
        /// Path to the license Aspose.OMR.NET.lic file
        /// </summary>
        private static readonly string LicensePath = @"C:\Users\Dell\Documents\Education Galaxy\super sheets\OMR\omrscanbubblesheet\testcode\TestData\Aspose.OMR.lic";

        /// <summary>
        /// User images to recognize
        /// </summary>
        private static readonly string[] UserImages = new string[] { "6e678c90-b5ab-445f-a904-454de3a46ee9.jpg" };// "finaltemplate2.JPG" };// "Photo1.jpg", "testrecognistion.jpg" }; // "c460992f-b3fa-4a9b-bc1e-8ba438d67fd8.jpg" };// "6aba1cc3-9e82-4922-8f89-28acdba9eaac.jpg" };//"recognitionTest.jpg", "bubblesheet.jpg", "bubblesheet2.jpg" };//"file-11.jpeg" };//, "testrecognistion.PNG", "87117a7f-d0fa-425c-98bf-9362524eca1e.jpg", "5b8fe9ff-8a99-4561-a7d1-d1cdf7c6e9c0.jpg" };// "recognitionTest.jpg" };//,"Sheet1.jpg", "Sheet2.jpg" };

        /// <summary>
        /// Starting point of the demo
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Set license, provide LicensePath and uncomment to test full results
            SetLicense();

            // Recognize images
            Recognize();
            //store data into database...

            Console.WriteLine();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }



        private static void SetLicense()
        {
            License lic = new License();
            lic.SetLicense(LicensePath);
            Console.WriteLine("License is set.");
        }

        /// <summary>
        /// Method demonstrated full OMR workflow.
        /// </summary>
        public static void Recognize()
        {
            // Set custom threshold to use in recalculation
            int CustomThreshold = 40;

            string testFolderPath = Path.Combine(FindDataFolder(), TestDataFolderName);
            Console.WriteLine("Test folder located. Path: " + testFolderPath);

            string templatePath = Path.Combine(testFolderPath, TemplateName);

            string outputPath = Path.Combine(testFolderPath, "Result");
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            // init engine and get template processor
            OmrEngine engine = new OmrEngine();
            TemplateProcessor templateProcessor = engine.GetTemplateProcessor(templatePath);


            Console.WriteLine("Template loaded.");

            for (int i = 0; i < UserImages.Length; i++)
            {
                string image = UserImages[i];
                string imagePath = Path.Combine(testFolderPath, image);
                Console.WriteLine("Processing image: " + imagePath);

                // recognize image
                RecognitionResult result = templateProcessor.RecognizeImage(imagePath);


                // get export csv string
                string stringRes = result.GetCsv();

                stringRes = stringRes.Replace("Element Name, Value,", "");
                stringRes = stringRes.Replace("\r\n", ".");
                string[] studentChoice = stringRes.Split('.').ToArray();


                Console.WriteLine(stringRes);
                studentChoice = studentChoice.Skip(1).ToArray();
                studentChoice = studentChoice.Take(studentChoice.Count() - 1).ToArray();

                List<SupersheetStudentAnswer> supersheetStudentAnswers = new List<SupersheetStudentAnswer>();
                SupersheetStudentAnswer supersheetStudentAnswer = new SupersheetStudentAnswer();
                foreach (var item in studentChoice)
                {
                    var questionNumber = item.Split(',')[0].Replace("Question",string.Empty);
                    var answer = item.Split(',')[1];

                    supersheetStudentAnswer.QuestionNumber = int.Parse(questionNumber);
                    switch (answer.ToUpper())
                    {
                        case "A":
                        case "F":
                            supersheetStudentAnswer.AnswerAF = true;
                            break;
                        case "B":
                        case "G":
                            supersheetStudentAnswer.AnswerBG = true;
                            break;
                        case "C":
                        case "H":
                            supersheetStudentAnswer.AnswerCH = true;
                            break;
                        case "D":
                        case "J":
                            supersheetStudentAnswer.AnswerDJ = true;
                            break;                       
                    }
                    supersheetStudentAnswers.Add(supersheetStudentAnswer);
                }
              
                Console.WriteLine();
            }
        }

        /// <summary>
        /// Silent and short version of recognition workflow
        /// </summary>
        public static void RecognizeShort()
        {
            // ---------------------------------------
            // input and output preparation
            string testFolderPath = Path.Combine(FindDataFolder(), TestDataFolderName);
            Console.WriteLine("Test folder located. Path: " + testFolderPath);

            string templatePath = Path.Combine(testFolderPath, TemplateName);
            string outputPath = Path.Combine(testFolderPath, "Result");
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }
            // ---------------------------------------



            // actual OMR API calls
            OmrEngine engine = new OmrEngine();
            TemplateProcessor templateProcessor = engine.GetTemplateProcessor(templatePath);

            for (int i = 0; i < UserImages.Length; i++)
            {
                string imagePath = Path.Combine(testFolderPath, UserImages[i]);
                string csvResult = templateProcessor.RecognizeImage(imagePath).GetCsv();

                File.WriteAllText(Path.Combine(outputPath, UserImages[i] + ".csv"), csvResult);
            }
        }

        /// <summary>
        /// Finds specified test data folder
        /// </summary>
        /// <returns>Path to the test data folder</returns>
        private static string FindDataFolder()
        {
            DirectoryInfo current = new DirectoryInfo(Directory.GetCurrentDirectory());
            string templateRelPath = Path.Combine(TestDataFolderName, TemplateName);

            // Locate test data folder containing .omr file
            while (current != null && !File.Exists(Path.Combine(current.FullName, templateRelPath)))
            {
                current = current.Parent;
            }

            // Check if template file exists
            if (current == null)
            {
                throw new Exception("Unable to find template file (.omr)");
            }

            return current.FullName;
        }

        private static IEnumerable<string> StringToList(string str)
        {
            if (String.IsNullOrEmpty(str))
                yield break;

            foreach (var s in str.Split('.'))
            {
                string result;
                yield return result = s;

            }

        }
    }
}

@bvaidya

Thanks for sharing code snippet.

Your code snippet is using some image and template files which are not attached your post and are required to test the scenario. Would you please share them as well so that we can test the scenario accordingly.

@asad.ali
Thank you for your reply.

I have attached image and template files to test the code. 23july2019-send template to aspose.zip (233.1 KB)

We required new template file(.omr) using this image templateFinal.png (80.6 KB)
that can process the image 6e678c90-b5ab-445f-a904-454de3a46ee9.jpg (171.3 KB)
Can you please create template file(.omr) and send us, so that we can test with new image and process the answers?

@bvaidya

We believe this is the same issue and files which have shared in other thread. We will be sharing our feedback there and we request you to follow up there.